mitao
2024-08-22 b4e0d41d741448cf03515bc6370db81f1b61f259
提交项目基础代码
972个文件已添加
79896 ■■■■■ 已修改文件
LICENSE 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/clean.bat 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/package.bat 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-auth.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-gateway.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-modules-file.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-modules-gen.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-modules-job.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-modules-system.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
bin/run-monitor.bat 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/copy.sh 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/deploy.sh 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/mysql/db/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/mysql/dockerfile 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/nacos/conf/application.properties 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/nacos/dockerfile 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/nginx/conf/nginx.conf 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/nginx/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/redis/conf/redis.conf 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/redis/dockerfile 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/auth/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/auth/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/gateway/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/gateway/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/file/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/file/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/gen/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/gen/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/job/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/job/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/system/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/modules/system/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/visual/monitor/dockerfile 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
docker/ruoyi/visual/monitor/jar/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json 3762 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package.json 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/quartz.sql 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/ry_20230223.sql 695 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/ry_config_20220929.sql 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sql/ry_seata_20210128.sql 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/pom.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/pom.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/factory/RemoteCourseFallbackFactory.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-course/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/pom.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-meditation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/pom.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/pom.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteFileService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteLogService.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteUserService.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/DataUpdateHandlerConfig.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/HttpConfig.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/MybatisPlusConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDept.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDictData.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDictType.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysFile.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysLogininfor.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysOperLog.java 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysRole.java 256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java 356 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteFileFallbackFactory.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteLogFallbackFactory.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteUserFallbackFactory.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/SysUserFallbackFactory.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/feignClient/SysUserClient.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyAddSysUserDto.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanySysUserReq.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyUserListVo.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/LoginUser.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/SysUserRoleDTO.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAdd.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAddDto.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/pom.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/AppUser.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/AppUserDTO.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-api/xinquan-api-user/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/pom.xml 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/XinQuanAuthApplication.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/AppRegisterBody.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/LoginBody.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/form/RegisterBody.java 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/service/SysPasswordService.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/java/com/xinquan/auth/service/SysRecordLogService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-auth/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/pom.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/pom.xml 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/annotation/Excel.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/annotation/Excels.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/GenConstants.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/HttpStatus.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ScheduleConstants.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/SecurityConstants.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ServiceNameConstants.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/TokenConstants.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/UserConstants.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/context/SecurityContextHolder.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/domain/R.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ApproveConfigEnum.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditStateEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditTypeEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarColorEnum.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarStateEnum.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractStateEnum.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractTypeEnum.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/DisabledEnum.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/HandoverStateEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ImportTypeEnum.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/InsureTypeEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PurchaseStateEnum.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnCarTypeEnum.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnStateEnum.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/UserStatus.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/WarrantyStateEnum.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/CaptchaException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/CheckedException.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/DemoModeException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/GlobalException.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/InnerAuthException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/PreAuthorizeException.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/ServiceException.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/UtilException.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotLoginException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotPermissionException.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotRoleException.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/base/BaseException.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileException.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileNameLengthLimitExceededException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileSizeLimitExceededException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileUploadException.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/InvalidExtensionException.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/job/TaskException.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/CaptchaExpireException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/UserException.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/UserPasswordNotMatchException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/query/TimeRangePageQuery.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/CharsetKit.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/Convert.java 1006 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/StrFormatter.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/DateUtils.java 366 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ExceptionUtil.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ImportExcelUtil.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/JwtUtils.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/PageUtils.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ServletUtils.java 333 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/SpringUtils.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/StringUtils.java 561 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/WebUtils.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/bean/BeanUtils.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/bean/BeanValidators.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/FileTypeUtils.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/FileUtils.java 253 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/ImageUtils.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/MimeTypeUtils.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/html/EscapeUtil.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/html/HTMLFilter.java 570 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ip/IpUtils.java 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/obs/OBSUtil.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/ArrayUtils.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/BeanUtils.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/Checker.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/CollUtils.java 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/Convert.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/NumberUtils.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/ObjectUtils.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/PageDTO.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/poi/ExcelHandlerAdapter.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/poi/ExcelUtil.java 1487 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/reflect/ReflectUtils.java 410 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/sign/Base64.java 291 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/sql/SqlUtil.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/IdUtils.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/Seq.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/UUID.java 484 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/controller/BaseController.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/AjaxResult.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseEntity.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/TreeEntity.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/BasePage.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/PageDomain.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/PageInfo.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/TableDataInfo.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/TableSupport.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/xss/Xss.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/xss/XssValidator.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datascope/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datascope/src/main/java/com/xinquan/common/datascope/annotation/DataScope.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datascope/src/main/java/com/xinquan/common/datascope/aspect/DataScopeAspect.java 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datasource/pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datasource/src/main/java/com/xinquan/common/datasource/annotation/Master.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-datasource/src/main/java/com/xinquan/common/datasource/annotation/Slave.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/annotation/Log.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/aspect/LogAspect.java 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/BusinessStatus.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/BusinessType.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/OperatorType.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/filter/PropertyPreExcludeFilter.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/service/AsyncLogService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-redis/pom.xml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/configure/FastJson2JsonRedisSerializer.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/configure/RedisConfig.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/service/RedisService.java 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-seata/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/pom.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableCustomConfig.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableRyFeignClients.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/InnerAuth.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/Logical.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresLogin.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresPermissions.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresRoles.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/aspect/InnerAuthAspect.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/aspect/PreAuthorizeAspect.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/auth/AuthLogic.java 373 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/auth/AuthUtil.java 167 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/ApplicationConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/JacksonConfig.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/LocalDateTimeSerializerConfig.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/WebMvcConfig.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/feign/FeignAutoConfiguration.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/feign/FeignRequestInterceptor.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/handler/GlobalExceptionHandler.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/interceptor/HeaderInterceptor.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/service/TokenService.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/utils/DictUtils.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/utils/SecurityUtils.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/pom.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/annotation/EnableCustomSwagger2.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerAutoConfiguration.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerBeanPostProcessor.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerProperties.java 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerWebConfiguration.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-common/xinquan-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/pom.xml 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/XinQuanGatewayApplication.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/CaptchaConfig.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/GatewayConfig.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/KaptchaTextCreator.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/RouterFunctionConfiguration.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/SwaggerProvider.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/CaptchaProperties.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/IgnoreWhiteProperties.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/XssProperties.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/filter/AuthFilter.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/filter/BlackListUrlFilter.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/filter/CacheRequestFilter.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/filter/ValidateCodeFilter.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/filter/XssFilter.java 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/handler/GatewayExceptionHandler.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/handler/SentinelFallbackHandler.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/handler/SwaggerHandler.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/handler/ValidateCodeHandler.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/service/ValidateCodeService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/java/com/xinquan/gateway/service/impl/ValidateCodeServiceImpl.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-gateway/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/pom.xml 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/pom.xml 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/XinQuanCourseApplication.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseCategoryController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseChapterController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnCourseController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseCategoryController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseChapterController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtTutorSpecialColumnController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtTutorSpecialColumnCourseController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/Course.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseCategory.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseChapter.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumn.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumnCourse.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseCategoryMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseChapterMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/TutorSpecialColumnCourseMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/TutorSpecialColumnMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseCategoryService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseChapterService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/TutorSpecialColumnCourseService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/TutorSpecialColumnService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseCategoryServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseChapterServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/TutorSpecialColumnCourseServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/TutorSpecialColumnServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-course/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/pom.xml 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/XinQuanFileApplication.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/config/MinioConfig.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/config/ResourcesConfig.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/FastDfsSysFileServiceImpl.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/ISysFileService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/LocalSysFileServiceImpl.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/MinioSysFileServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/FileUploadUtils.java 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-file/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/pom.xml 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/RuoYiGenApplication.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/config/GenConfig.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/controller/GenController.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/domain/GenTable.java 370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/domain/GenTableColumn.java 374 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/mapper/GenTableColumnMapper.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/mapper/GenTableMapper.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/GenTableColumnServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/GenTableServiceImpl.java 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/IGenTableColumnService.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/IGenTableService.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/GenUtils.java 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/VelocityInitializer.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/VelocityUtils.java 402 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/mapper/generator/GenTableMapper.xml 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/controller.java.vm 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/domain.java.vm 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/mapper.java.vm 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/service.java.vm 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/serviceImpl.java.vm 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/java/sub-domain.java.vm 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/js/api.js.vm 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/sql/sql.vm 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/vue/index-tree.vue.vm 505 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/vue/index.vue.vm 602 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm 474 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/index.vue.vm 590 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/readme.txt 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-gen/src/main/resources/vm/xml/mapper.xml.vm 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/pom.xml 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/RuoYiJobApplication.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/config/ScheduleConfig.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/controller/SysJobController.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/controller/SysJobLogController.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/domain/SysJob.java 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/domain/SysJobLog.java 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/mapper/SysJobLogMapper.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/mapper/SysJobMapper.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/ISysJobLogService.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/ISysJobService.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/SysJobLogServiceImpl.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/SysJobServiceImpl.java 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/task/RyTask.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/AbstractQuartzJob.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/CronUtils.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/JobInvokeUtil.java 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/QuartzDisallowConcurrentExecution.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/QuartzJobExecution.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/ScheduleUtils.java 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/resources/mapper/job/SysJobLogMapper.xml 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-job/src/main/resources/mapper/job/SysJobMapper.xml 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/pom.xml 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/XinQuanMeditationApplication.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationCategoryController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationEverydayController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationHallController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationMusicController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationQuestionController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationTagController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationUserOperationController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtClientMeditationUserOperationController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationCategoryController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationEverydayController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationHallController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationMusicController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationQuestionController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationTagController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/Meditation.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationCategory.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationHall.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationMusic.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationQuestion.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationTag.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationUserOperation.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationCategoryMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationEverydayMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationHallMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMusicMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationQuestionMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationTagMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationUserOperationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationCategoryService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationEverydayService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationHallService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationMusicService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationQuestionService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationTagService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationUserOperationService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationCategoryServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationEverydayServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationHallServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationMusicServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationQuestionServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationTagServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationUserOperationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationCategoryMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationEverydayMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationHallMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMusicMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationQuestionMapper.xml 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationTagMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-meditation/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/pom.xml 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/XinQuanOrderApplication.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderPaymentRecordController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderPaymentRecordController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/Order.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/OrderPaymentRecord.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderPaymentRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderPaymentRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderPaymentRecordServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-order/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/pom.xml 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/XinQuanSystemApplication.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/BannerController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommonQuestionController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/ContentSettingController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CustomConfigController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HomeBackgroundMusicController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HotWordsController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysConfigController.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDeptController.java 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDictDataController.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDictTypeController.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysLogininforController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysMenuController.java 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysNoticeController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysOperlogController.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysPostController.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysProfileController.java 166 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysRoleController.java 479 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserController.java 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserOnlineController.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserRoleController.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/TreeLevelSettingController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/UserLevelSettingController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VersionController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VipSettingController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Banner.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommonQuestion.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/ContentSetting.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CustomConfig.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HomeBackgroundMusic.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HotWords.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysConfig.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysMenu.java 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysMenus.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysNotice.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysPost.java 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysRoleDept.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysRoleMenu.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserOnline.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserPost.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserRole.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/TreeLevelSetting.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/UserLevelSetting.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Version.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/VipSetting.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/dto/RoleAddDto.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/dto/RoleUpdateDto.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/MetaVo.java 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/RoleInfoVo.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/RouterVo.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/TreeSelect.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/BannerMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CommonQuestionMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/ContentSettingMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CustomConfigMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/HomeBackgroundMusicMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/HotWordsMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysConfigMapper.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDeptMapper.java 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDictDataMapper.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDictTypeMapper.java 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysLogininforMapper.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysMenuMapper.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysNoticeMapper.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysOperLogMapper.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysPostMapper.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleDeptMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleMapper.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleMenuMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserMapper.java 146 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserPostMapper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserRoleMapper.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/TreeLevelSettingMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/UserLevelSettingMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/VersionMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/VipSettingMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/query/SysOperLogQuery.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysConfigService.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDeptService.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDictDataService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDictTypeService.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysLogininforService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysMenuService.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysNoticeService.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysOperLogService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysPermissionService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysPostService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysRoleService.java 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserOnlineService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserRoleService.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserService.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysConfigServiceImpl.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDeptServiceImpl.java 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDictDataServiceImpl.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDictTypeServiceImpl.java 225 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysLogininforServiceImpl.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysMenuServiceImpl.java 572 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysNoticeServiceImpl.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysOperLogServiceImpl.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysPermissionServiceImpl.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysPostServiceImpl.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysRoleServiceImpl.java 446 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserOnlineServiceImpl.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserRoleServiceImpl.java 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserServiceImpl.java 583 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/BannerMapper.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/CommonQuestionMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/ContentSettingMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/CustomConfigMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/HomeBackgroundMusicMapper.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/HotWordsMapper.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysConfigMapper.xml 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDeptMapper.xml 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDictDataMapper.xml 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDictTypeMapper.xml 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysLogininforMapper.xml 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysMenuMapper.xml 275 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysNoticeMapper.xml 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysOperLogMapper.xml 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysPostMapper.xml 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleMapper.xml 155 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserMapper.xml 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserPostMapper.xml 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserRoleMapper.xml 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/TreeLevelSettingMapper.xml 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/UserLevelSettingMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/VersionMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mapper/system/VipSettingMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-system/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/pom.xml 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/XinQuanUserApplication.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserBankController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserCourseController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserEnergyRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserMeditationController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTagController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTreeController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWalletRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWithdrawController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeRedemptionRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientTagController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerAppUserController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserBankController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserCourseController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserEnergyRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserMeditationController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTagController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTreeController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWalletRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWithdrawController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeRedemptionRecordController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtTagController.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserBank.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserCourse.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserEnergyRecord.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserMeditation.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTag.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTree.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserWalletRecord.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserWithdraw.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Prize.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/PrizeRedemptionRecord.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Tag.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserBankMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserCourseMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserEnergyRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserMeditationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserTagMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserTreeMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserWalletRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserWithdrawMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/PrizeMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/PrizeRedemptionRecordMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/TagMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserBankService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserCourseService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserEnergyRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserMeditationService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserService.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserTagService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserTreeService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserWalletRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserWithdrawService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/PrizeRedemptionRecordService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/PrizeService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/TagService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserBankServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserCourseServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserEnergyRecordServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserMeditationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserTagServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserTreeServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserWalletRecordServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserWithdrawServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/PrizeRedemptionRecordServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/PrizeServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/TagServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserBankMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserCourseMapper.xml 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserEnergyRecordMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserMapper.xml 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserMeditationMapper.xml 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTagMapper.xml 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTreeMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserWalletRecordMapper.xml 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserWithdrawMapper.xml 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/PrizeMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/PrizeRedemptionRecordMapper.xml 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mapper/user/TagMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-modules/xinquan-user/src/main/resources/mybatis-config.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.editorconfig 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.env.development 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.env.production 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.env.staging 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.eslintignore 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.eslintrc.js 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/.gitignore 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/README.md 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/babel.config.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/bin/build.bat 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/bin/package.bat 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/bin/run-web.bat 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/build/index.js 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/package.json 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/public/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/public/html/ie.html 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/public/index.html 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/public/robots.txt 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/App.vue 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/login.js 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/menu.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/monitor/job.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/monitor/jobLog.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/monitor/online.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/config.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/dept.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/dict/data.js 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/dict/type.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/logininfor.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/menu.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/notice.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/operlog.js 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/post.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/role.js 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/system/user.js 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/api/tool/gen.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/401_images/401.gif 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/404_images/404.png 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/404_images/404_cloud.png 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/index.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/404.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/bug.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/build.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/button.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/cascader.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/chart.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/checkbox.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/client.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/clipboard.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/code.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/color.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/component.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/dashboard.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/date-range.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/date.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/dict.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/documentation.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/download.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/drag.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/druid.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/edit.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/education.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/email.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/example.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/excel.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/exit-fullscreen.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/eye-open.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/eye.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/form.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/fullscreen.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/github.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/guide.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/icon.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/input.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/international.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/job.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/language.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/link.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/list.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/lock.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/log.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/logininfor.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/message.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/money.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/monitor.svg 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/nacos.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/nested.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/number.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/online.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/password.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/pdf.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/people.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/peoples.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/phone.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/post.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/qq.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/question.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/radio.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/rate.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/row.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/search.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/select.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/sentinel.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/server.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/shopping.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/size.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/skill.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/slider.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/star.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/swagger.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/switch.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/system.svg 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/tab.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/table.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/textarea.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/theme.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/time-range.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/time.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/tool.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/tree-table.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/tree.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/upload.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/user.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/validCode.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/wechat.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/icons/svg/zip.svg 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/images/dark.svg 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/images/light.svg 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/images/login-background.jpg 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/images/profile.jpg 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/logo/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/btn.scss 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/element-ui.scss 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/element-variables.scss 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/index.scss 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/mixin.scss 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/ruoyi.scss 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/sidebar.scss 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/transition.scss 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/assets/styles/variables.scss 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Breadcrumb/index.vue 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/day.vue 161 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/hour.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/index.vue 430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/min.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/month.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/result.vue 559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/second.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/week.vue 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Crontab/year.vue 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/DictData/index.js 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/DictTag/index.vue 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Editor/index.vue 272 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/FileUpload/index.vue 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Hamburger/index.vue 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/HeaderSearch/index.vue 189 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/IconSelect/index.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/IconSelect/requireIcons.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/ImagePreview/index.vue 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/ImageUpload/index.vue 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Pagination/index.vue 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/PanThumb/index.vue 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/ParentView/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/RightPanel/index.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/RightToolbar/index.vue 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/RuoYi/Doc/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/RuoYi/Git/index.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/Screenfull/index.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/SizeSelect/index.vue 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/SvgIcon/index.vue 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/ThemePicker/index.vue 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/TopNav/index.vue 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/components/iFrame/index.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/dialog/drag.js 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/dialog/dragHeight.js 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/dialog/dragWidth.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/index.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/module/clipboard.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/permission/hasPermi.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/directive/permission/hasRole.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/AppMain.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/IframeToggle/index.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/InnerLink/index.vue 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Navbar.vue 200 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Settings/index.vue 260 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/FixiOSBug.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/Item.vue 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/Link.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/Logo.vue 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/SidebarItem.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/Sidebar/index.vue 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/TagsView/ScrollPane.vue 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/TagsView/index.vue 332 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/components/index.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/index.vue 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/layout/mixin/ResizeHandler.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/main.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/permission.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/auth.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/cache.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/download.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/index.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/modal.js 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/plugins/tab.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/router/index.js 183 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/settings.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/getters.js 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/index.js 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/app.js 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/dict.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/permission.js 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/settings.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/tagsView.js 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/store/modules/user.js 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/auth.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/Dict.js 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/DictConverter.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/DictData.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/DictMeta.js 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/DictOptions.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/dict/index.js 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/errorCode.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/config.js 438 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/css.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/drawingDefault.js 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/html.js 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/icon.json 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/js.js 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/generator/render.js 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/index.js 390 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/jsencrypt.js 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/permission.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/request.js 151 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/ruoyi.js 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/scroll-to.js 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/utils/validate.js 83 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/components/icons/element-icons.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/components/icons/index.vue 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/components/icons/svg-icons.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/BarChart.vue 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/LineChart.vue 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/PanelGroup.vue 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/PieChart.vue 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/RaddarChart.vue 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/dashboard/mixins/resize.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/error/401.vue 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/error/404.vue 233 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/index.vue 918 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/index_v1.vue 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/login.vue 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/monitor/job/index.vue 513 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/monitor/job/log.vue 295 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/monitor/online/index.vue 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/redirect.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/register.vue 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/config/index.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/dept/index.vue 336 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/dict/data.vue 402 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/dict/index.vue 347 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/logininfor/index.vue 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/menu/index.vue 452 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/notice/index.vue 312 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/operlog/index.vue 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/post/index.vue 309 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/role/authUser.vue 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/role/index.vue 605 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/role/selectUser.vue 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/authRole.vue 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/index.vue 670 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/profile/index.vue 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/profile/resetPwd.vue 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/profile/userAvatar.vue 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/system/user/profile/userInfo.vue 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/CodeTypeDialog.vue 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/DraggableItem.vue 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/IconsDialog.vue 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/RightPanel.vue 946 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/TreeNodeDialog.vue 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/build/index.vue 768 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/gen/basicInfoForm.vue 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/gen/editTable.vue 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/gen/genInfoForm.vue 299 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/gen/importTable.vue 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/src/views/tool/gen/index.vue 337 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-ui/vue.config.js 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/pom.xml 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/pom.xml 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/src/main/java/com/xinquan/modules/monitor/RuoYiMonitorApplication.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/src/main/java/com/xinquan/modules/monitor/config/WebSecurityConfigurer.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/src/main/resources/banner.txt 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
xinquan-visual/xinquan-monitor/src/main/resources/logback.xml 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
LICENSE
New file
@@ -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.
bin/clean.bat
New file
@@ -0,0 +1,12 @@
@echo off
echo.
echo [ÐÅÏ¢] ÇåÀí¹¤³ÌtargetÉú³É·¾¶¡£
echo.
%~d0
cd %~dp0
cd ..
call mvn clean
pause
bin/package.bat
New file
@@ -0,0 +1,12 @@
@echo off
echo.
echo [ÐÅÏ¢] ´ò°üWeb¹¤³Ì£¬Éú³Éwar/jar°üÎļþ¡£
echo.
%~d0
cd %~dp0
cd ..
call mvn clean package -Dmaven.test.skip=true
pause
bin/run-auth.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐAuth¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-auth/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-auth.jar
cd bin
pause
bin/run-gateway.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐGateway¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-gateway/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-gateway.jar
cd bin
pause
bin/run-modules-file.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐModules-File¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-modules/xinquan-file/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-modules-file.jar
cd bin
pause
bin/run-modules-gen.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐModules-Gen¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-modules/xinquan-gen/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-modules-gen.jar
cd bin
pause
bin/run-modules-job.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐModules-Job¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-modules/xinquan-job/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-modules-job.jar
cd bin
pause
bin/run-modules-system.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐModules-System¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-modules/xinquan-system/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-modules-system.jar
cd bin
pause
bin/run-monitor.bat
New file
@@ -0,0 +1,14 @@
@echo off
echo.
echo [ÐÅÏ¢] Ê¹ÓÃJarÃüÁîÔËÐÐMonitor¹¤³Ì¡£
echo.
cd %~dp0
cd ../xinquan-visual/xinquan-monitor/target
set JAVA_OPTS=-Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -Dfile.encoding=utf-8 %JAVA_OPTS% -jar xinquan-visual-monitor.jar
cd bin
pause
docker/copy.sh
New file
@@ -0,0 +1,41 @@
#!/bin/sh
# 复制项目的文件到对应docker路径,便于一键生成镜像。
usage() {
    echo "Usage: sh copy.sh"
    exit 1
}
# copy sql
echo "begin copy sql "
cp ../sql/ry_20230223.sql ./mysql/db
cp ../sql/ry_config_20220929.sql ./mysql/db
# copy html
echo "begin copy html "
cp -r ../xinquan-ui/dist/** ./nginx/html/dist
# copy jar
echo "begin copy xinquan-gateway "
cp ../xinquan-gateway/target/xinquan-gateway.jar ./ruoyi/gateway/jar
echo "begin copy xinquan-auth "
cp ../xinquan-auth/target/xinquan-auth.jar ./ruoyi/auth/jar
echo "begin copy xinquan-visual "
cp ../xinquan-visual/xinquan-monitor/target/xinquan-visual-monitor.jar  ./ruoyi/visual/monitor/jar
echo "begin copy xinquan-modules-system "
cp ../xinquan-modules/xinquan-system/target/xinquan-modules-system.jar ./ruoyi/modules/system/jar
echo "begin copy xinquan-modules-file "
cp ../xinquan-modules/xinquan-file/target/xinquan-modules-file.jar ./ruoyi/modules/file/jar
echo "begin copy xinquan-modules-job "
cp ../xinquan-modules/xinquan-job/target/xinquan-modules-job.jar ./ruoyi/modules/job/jar
echo "begin copy xinquan-modules-gen "
cp ../xinquan-modules/xinquan-gen/target/xinquan-modules-gen.jar ./ruoyi/modules/gen/jar
docker/deploy.sh
New file
@@ -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 xinquan-mysql xinquan-redis xinquan-nacos
}
# 启动程序模块(必须)
modules(){
    docker-compose up -d xinquan-nginx xinquan-gateway xinquan-auth xinquan-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
docker/mysql/db/readme.txt
New file
@@ -0,0 +1 @@
´æ·ÅsqlĿ¼ÏµÄËùÓнű¾£¬ÓÃÓÚdocker×Ô¶¯Ö´ÐС£
docker/mysql/dockerfile
New file
@@ -0,0 +1,7 @@
# 基础镜像
FROM mysql:5.7
# author
MAINTAINER ruoyi
# 执行sql脚本
ADD ./db/*.sql /docker-entrypoint-initdb.d/
docker/nacos/conf/application.properties
New file
@@ -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
docker/nacos/dockerfile
New file
@@ -0,0 +1,7 @@
# 基础镜像
FROM nacos/nacos-server
# author
MAINTAINER ruoyi
# 复制conf文件到路径
COPY ./conf/application.properties /home/nacos/conf/application.properties
docker/nginx/conf/nginx.conf
New file
@@ -0,0 +1,41 @@
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/;
        }
        # 避免actuator暴露
        if ($request_uri ~ "/actuator") {
            return 403;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
docker/nginx/dockerfile
New file
@@ -0,0 +1,15 @@
# 基础镜像
FROM nginx
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi/projects/xinquan-ui
# 创建目录
RUN mkdir -p /home/ruoyi/projects/xinquan-ui
# 指定路径
WORKDIR /home/ruoyi/projects/xinquan-ui
# 复制conf文件到路径
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
# 复制html文件到路径
COPY ./html/dist /home/ruoyi/projects/xinquan-ui
docker/redis/conf/redis.conf
New file
@@ -0,0 +1 @@
# requirepass 123456
docker/redis/dockerfile
New file
@@ -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
docker/ruoyi/auth/dockerfile
New file
@@ -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/xinquan-auth.jar /home/ruoyi/xinquan-auth.jar
# 启动认证服务
ENTRYPOINT ["java","-jar","xinquan-auth.jar"]
docker/ruoyi/auth/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·ÅÈÏÖ¤ÖÐÐÄ´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/gateway/dockerfile
New file
@@ -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/xinquan-gateway.jar /home/ruoyi/xinquan-gateway.jar
# 启动网关服务
ENTRYPOINT ["java","-jar","xinquan-gateway.jar"]
docker/ruoyi/gateway/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·ÅÍø¹ØÄ£¿é´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/modules/file/dockerfile
New file
@@ -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/xinquan-modules-file.jar /home/ruoyi/xinquan-modules-file.jar
# 启动文件服务
ENTRYPOINT ["java","-jar","xinquan-modules-file.jar"]
docker/ruoyi/modules/file/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·ÅÎļþ·þÎñ´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/modules/gen/dockerfile
New file
@@ -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/xinquan-modules-gen.jar /home/ruoyi/xinquan-modules-gen.jar
# 启动代码生成服务
ENTRYPOINT ["java","-jar","xinquan-modules-gen.jar"]
docker/ruoyi/modules/gen/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·Å´úÂëÉú³É´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/modules/job/dockerfile
New file
@@ -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/xinquan-modules-job.jar /home/ruoyi/xinquan-modules-job.jar
# 启动定时任务服务
ENTRYPOINT ["java","-jar","xinquan-modules-job.jar"]
docker/ruoyi/modules/job/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·Å¶¨Ê±ÈÎÎñ´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/modules/system/dockerfile
New file
@@ -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/xinquan-modules-system.jar /home/ruoyi/xinquan-modules-system.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","xinquan-modules-system.jar"]
docker/ruoyi/modules/system/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·Åϵͳģ¿é´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
docker/ruoyi/visual/monitor/dockerfile
New file
@@ -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/xinquan-visual-monitor.jar /home/ruoyi/xinquan-visual-monitor.jar
# 启动系统服务
ENTRYPOINT ["java","-jar","xinquan-visual-monitor.jar"]
docker/ruoyi/visual/monitor/jar/readme.txt
New file
@@ -0,0 +1 @@
´æ·Å¼à¿ØÖÐÐÄ´ò°üºÃµÄjarÎļþ£¬ÓÃÓÚdockerÆô¶¯Ó¦Óá£
package-lock.json
New file
@@ -0,0 +1,3762 @@
{
  "name": "RuoYi-Cloud",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "dependencies": {
        "node-sass": "^9.0.0"
      }
    },
    "node_modules/@babel/code-frame": {
      "version": "7.21.4",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
      "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
      "dependencies": {
        "@babel/highlight": "^7.18.6"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/helper-validator-identifier": {
      "version": "7.19.1",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==",
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/highlight": {
      "version": "7.18.6",
      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
      "dependencies": {
        "@babel/helper-validator-identifier": "^7.18.6",
        "chalk": "^2.0.0",
        "js-tokens": "^4.0.0"
      },
      "engines": {
        "node": ">=6.9.0"
      }
    },
    "node_modules/@babel/highlight/node_modules/ansi-styles": {
      "version": "3.2.1",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
      "dependencies": {
        "color-convert": "^1.9.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/@babel/highlight/node_modules/chalk": {
      "version": "2.4.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
      "dependencies": {
        "ansi-styles": "^3.2.1",
        "escape-string-regexp": "^1.0.5",
        "supports-color": "^5.3.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/@babel/highlight/node_modules/color-convert": {
      "version": "1.9.3",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
      "dependencies": {
        "color-name": "1.1.3"
      }
    },
    "node_modules/@babel/highlight/node_modules/color-name": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
    },
    "node_modules/@babel/highlight/node_modules/has-flag": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/@babel/highlight/node_modules/supports-color": {
      "version": "5.5.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
      "dependencies": {
        "has-flag": "^3.0.0"
      },
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/@gar/promisify": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
      "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="
    },
    "node_modules/@npmcli/fs": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
      "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
      "dependencies": {
        "@gar/promisify": "^1.1.3",
        "semver": "^7.3.5"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/@npmcli/move-file": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
      "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
      "deprecated": "This functionality has been moved to @npmcli/fs",
      "dependencies": {
        "mkdirp": "^1.0.4",
        "rimraf": "^3.0.2"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/@tootallnate/once": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/@types/minimist": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
      "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ=="
    },
    "node_modules/@types/normalize-package-data": {
      "version": "2.4.1",
      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
    },
    "node_modules/abbrev": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
    },
    "node_modules/agent-base": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
      "dependencies": {
        "debug": "4"
      },
      "engines": {
        "node": ">= 6.0.0"
      }
    },
    "node_modules/agentkeepalive": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
      "dependencies": {
        "debug": "^4.1.0",
        "depd": "^2.0.0",
        "humanize-ms": "^1.2.1"
      },
      "engines": {
        "node": ">= 8.0.0"
      }
    },
    "node_modules/aggregate-error": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
      "dependencies": {
        "clean-stack": "^2.0.0",
        "indent-string": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "dependencies": {
        "color-convert": "^2.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
      }
    },
    "node_modules/aproba": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
      "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
    },
    "node_modules/are-we-there-yet": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
      "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
      "dependencies": {
        "delegates": "^1.0.0",
        "readable-stream": "^3.6.0"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/arrify": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/async-foreach": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA==",
      "engines": {
        "node": "*"
      }
    },
    "node_modules/balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
    },
    "node_modules/brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "dependencies": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "node_modules/cacache": {
      "version": "16.1.3",
      "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
      "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
      "dependencies": {
        "@npmcli/fs": "^2.1.0",
        "@npmcli/move-file": "^2.0.0",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.1.0",
        "glob": "^8.0.1",
        "infer-owner": "^1.0.4",
        "lru-cache": "^7.7.1",
        "minipass": "^3.1.6",
        "minipass-collect": "^1.0.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "mkdirp": "^1.0.4",
        "p-map": "^4.0.0",
        "promise-inflight": "^1.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^9.0.0",
        "tar": "^6.1.11",
        "unique-filename": "^2.0.0"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/cacache/node_modules/brace-expansion": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
      "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
      "dependencies": {
        "balanced-match": "^1.0.0"
      }
    },
    "node_modules/cacache/node_modules/glob": {
      "version": "8.1.0",
      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^5.0.1",
        "once": "^1.3.0"
      },
      "engines": {
        "node": ">=12"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/cacache/node_modules/minimatch": {
      "version": "5.1.6",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
      "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
      "dependencies": {
        "brace-expansion": "^2.0.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/camelcase": {
      "version": "5.3.1",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/camelcase-keys": {
      "version": "6.2.2",
      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
      "dependencies": {
        "camelcase": "^5.3.1",
        "map-obj": "^4.0.0",
        "quick-lru": "^4.0.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "dependencies": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/chalk?sponsor=1"
      }
    },
    "node_modules/chownr": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/clean-stack": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/cliui": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
      "dependencies": {
        "string-width": "^4.2.0",
        "strip-ansi": "^6.0.1",
        "wrap-ansi": "^7.0.0"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "dependencies": {
        "color-name": "~1.1.4"
      },
      "engines": {
        "node": ">=7.0.0"
      }
    },
    "node_modules/color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
    },
    "node_modules/color-support": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
      "bin": {
        "color-support": "bin.js"
      }
    },
    "node_modules/concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
    },
    "node_modules/console-control-strings": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
    },
    "node_modules/core-util-is": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
    },
    "node_modules/cross-spawn": {
      "version": "7.0.3",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
      "dependencies": {
        "path-key": "^3.1.0",
        "shebang-command": "^2.0.0",
        "which": "^2.0.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/debug": {
      "version": "4.3.4",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
      "dependencies": {
        "ms": "2.1.2"
      },
      "engines": {
        "node": ">=6.0"
      },
      "peerDependenciesMeta": {
        "supports-color": {
          "optional": true
        }
      }
    },
    "node_modules/decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/decamelize-keys": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
      "dependencies": {
        "decamelize": "^1.1.0",
        "map-obj": "^1.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/decamelize-keys/node_modules/map-obj": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
      "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/delegates": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
    },
    "node_modules/depd": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
      "engines": {
        "node": ">= 0.8"
      }
    },
    "node_modules/emoji-regex": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
    },
    "node_modules/encoding": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
      "optional": true,
      "dependencies": {
        "iconv-lite": "^0.6.2"
      }
    },
    "node_modules/env-paths": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/err-code": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="
    },
    "node_modules/error-ex": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
      "dependencies": {
        "is-arrayish": "^0.2.1"
      }
    },
    "node_modules/escalade": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
      "engines": {
        "node": ">=0.8.0"
      }
    },
    "node_modules/find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "dependencies": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/fs-minipass": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
    },
    "node_modules/function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
    },
    "node_modules/gauge": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
      "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
      "dependencies": {
        "aproba": "^1.0.3 || ^2.0.0",
        "color-support": "^1.1.3",
        "console-control-strings": "^1.1.0",
        "has-unicode": "^2.0.1",
        "signal-exit": "^3.0.7",
        "string-width": "^4.2.3",
        "strip-ansi": "^6.0.1",
        "wide-align": "^1.1.5"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/gaze": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
      "dependencies": {
        "globule": "^1.0.0"
      },
      "engines": {
        "node": ">= 4.0.0"
      }
    },
    "node_modules/get-caller-file": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
      "engines": {
        "node": "6.* || 8.* || >= 10.*"
      }
    },
    "node_modules/get-stdin": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/glob": {
      "version": "7.2.3",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.1.1",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/globule": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
      "dependencies": {
        "glob": "~7.1.1",
        "lodash": "^4.17.21",
        "minimatch": "~3.0.2"
      },
      "engines": {
        "node": ">= 0.10"
      }
    },
    "node_modules/globule/node_modules/glob": {
      "version": "7.1.7",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
      "dependencies": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.0.4",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      },
      "engines": {
        "node": "*"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/globule/node_modules/minimatch": {
      "version": "3.0.8",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
      "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
    },
    "node_modules/hard-rejection": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "dependencies": {
        "function-bind": "^1.1.1"
      },
      "engines": {
        "node": ">= 0.4.0"
      }
    },
    "node_modules/has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/has-unicode": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
    },
    "node_modules/hosted-git-info": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
      "dependencies": {
        "lru-cache": "^6.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/hosted-git-info/node_modules/lru-cache": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/http-cache-semantics": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
      "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
    },
    "node_modules/http-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
      "dependencies": {
        "@tootallnate/once": "2",
        "agent-base": "6",
        "debug": "4"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/https-proxy-agent": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
      "dependencies": {
        "agent-base": "6",
        "debug": "4"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/humanize-ms": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
      "dependencies": {
        "ms": "^2.0.0"
      }
    },
    "node_modules/iconv-lite": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
      "optional": true,
      "dependencies": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/imurmurhash": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
      "engines": {
        "node": ">=0.8.19"
      }
    },
    "node_modules/indent-string": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/infer-owner": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
    },
    "node_modules/inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
      "dependencies": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "node_modules/inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
    },
    "node_modules/ip": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
    },
    "node_modules/is-arrayish": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
    },
    "node_modules/is-core-module": {
      "version": "2.12.1",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
      "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
      "dependencies": {
        "has": "^1.0.3"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/is-lambda": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="
    },
    "node_modules/is-plain-obj": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
    },
    "node_modules/isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
    },
    "node_modules/js-base64": {
      "version": "2.6.4",
      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
    },
    "node_modules/js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
    },
    "node_modules/json-parse-even-better-errors": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
    },
    "node_modules/kind-of": {
      "version": "6.0.3",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/lines-and-columns": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
    },
    "node_modules/locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "dependencies": {
        "p-locate": "^4.1.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    },
    "node_modules/lru-cache": {
      "version": "7.18.3",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/make-fetch-happen": {
      "version": "10.2.1",
      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
      "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
      "dependencies": {
        "agentkeepalive": "^4.2.1",
        "cacache": "^16.1.0",
        "http-cache-semantics": "^4.1.0",
        "http-proxy-agent": "^5.0.0",
        "https-proxy-agent": "^5.0.0",
        "is-lambda": "^1.0.1",
        "lru-cache": "^7.7.1",
        "minipass": "^3.1.6",
        "minipass-collect": "^1.0.2",
        "minipass-fetch": "^2.0.3",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "negotiator": "^0.6.3",
        "promise-retry": "^2.0.1",
        "socks-proxy-agent": "^7.0.0",
        "ssri": "^9.0.0"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/map-obj": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==",
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/meow": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
      "dependencies": {
        "@types/minimist": "^1.2.0",
        "camelcase-keys": "^6.2.2",
        "decamelize": "^1.2.0",
        "decamelize-keys": "^1.1.0",
        "hard-rejection": "^2.1.0",
        "minimist-options": "4.1.0",
        "normalize-package-data": "^3.0.0",
        "read-pkg-up": "^7.0.1",
        "redent": "^3.0.0",
        "trim-newlines": "^3.0.0",
        "type-fest": "^0.18.0",
        "yargs-parser": "^20.2.3"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/min-indent": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==",
      "engines": {
        "node": ">=4"
      }
    },
    "node_modules/minimatch": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
      "dependencies": {
        "brace-expansion": "^1.1.7"
      },
      "engines": {
        "node": "*"
      }
    },
    "node_modules/minimist-options": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
      "dependencies": {
        "arrify": "^1.0.1",
        "is-plain-obj": "^1.1.0",
        "kind-of": "^6.0.3"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/minipass": {
      "version": "3.3.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minipass-collect": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/minipass-fetch": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
      "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
      "dependencies": {
        "minipass": "^3.1.6",
        "minipass-sized": "^1.0.3",
        "minizlib": "^2.1.2"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      },
      "optionalDependencies": {
        "encoding": "^0.1.13"
      }
    },
    "node_modules/minipass-flush": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/minipass-pipeline": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minipass-sized": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
      "dependencies": {
        "minipass": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/minizlib": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
      "dependencies": {
        "minipass": "^3.0.0",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
      "bin": {
        "mkdirp": "bin/cmd.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    },
    "node_modules/nan": {
      "version": "2.17.0",
      "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
      "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
    },
    "node_modules/negotiator": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
      "engines": {
        "node": ">= 0.6"
      }
    },
    "node_modules/node-gyp": {
      "version": "8.4.1",
      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
      "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
      "dependencies": {
        "env-paths": "^2.2.0",
        "glob": "^7.1.4",
        "graceful-fs": "^4.2.6",
        "make-fetch-happen": "^9.1.0",
        "nopt": "^5.0.0",
        "npmlog": "^6.0.0",
        "rimraf": "^3.0.2",
        "semver": "^7.3.5",
        "tar": "^6.1.2",
        "which": "^2.0.2"
      },
      "bin": {
        "node-gyp": "bin/node-gyp.js"
      },
      "engines": {
        "node": ">= 10.12.0"
      }
    },
    "node_modules/node-gyp/node_modules/@npmcli/fs": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
      "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
      "dependencies": {
        "@gar/promisify": "^1.0.1",
        "semver": "^7.3.5"
      }
    },
    "node_modules/node-gyp/node_modules/@npmcli/move-file": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
      "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
      "deprecated": "This functionality has been moved to @npmcli/fs",
      "dependencies": {
        "mkdirp": "^1.0.4",
        "rimraf": "^3.0.2"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/node-gyp/node_modules/@tootallnate/once": {
      "version": "1.1.2",
      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
      "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/node-gyp/node_modules/cacache": {
      "version": "15.3.0",
      "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
      "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
      "dependencies": {
        "@npmcli/fs": "^1.0.0",
        "@npmcli/move-file": "^1.0.1",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "glob": "^7.1.4",
        "infer-owner": "^1.0.4",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.1",
        "minipass-collect": "^1.0.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.2",
        "mkdirp": "^1.0.3",
        "p-map": "^4.0.0",
        "promise-inflight": "^1.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^8.0.1",
        "tar": "^6.0.2",
        "unique-filename": "^1.1.1"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/node-gyp/node_modules/http-proxy-agent": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
      "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
      "dependencies": {
        "@tootallnate/once": "1",
        "agent-base": "6",
        "debug": "4"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/node-gyp/node_modules/lru-cache": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/node-gyp/node_modules/make-fetch-happen": {
      "version": "9.1.0",
      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
      "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
      "dependencies": {
        "agentkeepalive": "^4.1.3",
        "cacache": "^15.2.0",
        "http-cache-semantics": "^4.1.0",
        "http-proxy-agent": "^4.0.1",
        "https-proxy-agent": "^5.0.0",
        "is-lambda": "^1.0.1",
        "lru-cache": "^6.0.0",
        "minipass": "^3.1.3",
        "minipass-collect": "^1.0.2",
        "minipass-fetch": "^1.3.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "negotiator": "^0.6.2",
        "promise-retry": "^2.0.1",
        "socks-proxy-agent": "^6.0.0",
        "ssri": "^8.0.0"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/node-gyp/node_modules/minipass-fetch": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
      "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
      "dependencies": {
        "minipass": "^3.1.0",
        "minipass-sized": "^1.0.3",
        "minizlib": "^2.0.0"
      },
      "engines": {
        "node": ">=8"
      },
      "optionalDependencies": {
        "encoding": "^0.1.12"
      }
    },
    "node_modules/node-gyp/node_modules/socks-proxy-agent": {
      "version": "6.2.1",
      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
      "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
      "dependencies": {
        "agent-base": "^6.0.2",
        "debug": "^4.3.3",
        "socks": "^2.6.2"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/node-gyp/node_modules/ssri": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
      "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
      "dependencies": {
        "minipass": "^3.1.1"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/node-gyp/node_modules/unique-filename": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
      "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
      "dependencies": {
        "unique-slug": "^2.0.0"
      }
    },
    "node_modules/node-gyp/node_modules/unique-slug": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
      "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
      "dependencies": {
        "imurmurhash": "^0.1.4"
      }
    },
    "node_modules/node-sass": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-9.0.0.tgz",
      "integrity": "sha512-yltEuuLrfH6M7Pq2gAj5B6Zm7m+gdZoG66wTqG6mIZV/zijq3M2OO2HswtT6oBspPyFhHDcaxWpsBm0fRNDHPg==",
      "hasInstallScript": true,
      "dependencies": {
        "async-foreach": "^0.1.3",
        "chalk": "^4.1.2",
        "cross-spawn": "^7.0.3",
        "gaze": "^1.0.0",
        "get-stdin": "^4.0.1",
        "glob": "^7.0.3",
        "lodash": "^4.17.15",
        "make-fetch-happen": "^10.0.4",
        "meow": "^9.0.0",
        "nan": "^2.17.0",
        "node-gyp": "^8.4.1",
        "sass-graph": "^4.0.1",
        "stdout-stream": "^1.4.0",
        "true-case-path": "^2.2.1"
      },
      "bin": {
        "node-sass": "bin/node-sass"
      },
      "engines": {
        "node": ">=16"
      }
    },
    "node_modules/nopt": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
      "dependencies": {
        "abbrev": "1"
      },
      "bin": {
        "nopt": "bin/nopt.js"
      },
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/normalize-package-data": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
      "dependencies": {
        "hosted-git-info": "^4.0.1",
        "is-core-module": "^2.5.0",
        "semver": "^7.3.4",
        "validate-npm-package-license": "^3.0.1"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/npmlog": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
      "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
      "dependencies": {
        "are-we-there-yet": "^3.0.0",
        "console-control-strings": "^1.1.0",
        "gauge": "^4.0.3",
        "set-blocking": "^2.0.0"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
      "dependencies": {
        "wrappy": "1"
      }
    },
    "node_modules/p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "dependencies": {
        "p-try": "^2.0.0"
      },
      "engines": {
        "node": ">=6"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "dependencies": {
        "p-limit": "^2.2.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/p-map": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
      "dependencies": {
        "aggregate-error": "^3.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
      "engines": {
        "node": ">=6"
      }
    },
    "node_modules/parse-json": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
      "dependencies": {
        "@babel/code-frame": "^7.0.0",
        "error-ex": "^1.3.1",
        "json-parse-even-better-errors": "^2.3.0",
        "lines-and-columns": "^1.1.6"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/path-key": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
    },
    "node_modules/process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
    },
    "node_modules/promise-inflight": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="
    },
    "node_modules/promise-retry": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
      "dependencies": {
        "err-code": "^2.0.2",
        "retry": "^0.12.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/quick-lru": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/read-pkg": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
      "dependencies": {
        "@types/normalize-package-data": "^2.4.0",
        "normalize-package-data": "^2.5.0",
        "parse-json": "^5.0.0",
        "type-fest": "^0.6.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/read-pkg-up": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
      "dependencies": {
        "find-up": "^4.1.0",
        "read-pkg": "^5.2.0",
        "type-fest": "^0.8.1"
      },
      "engines": {
        "node": ">=8"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/read-pkg-up/node_modules/type-fest": {
      "version": "0.8.1",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
      "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/read-pkg/node_modules/hosted-git-info": {
      "version": "2.8.9",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
      "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
    },
    "node_modules/read-pkg/node_modules/normalize-package-data": {
      "version": "2.5.0",
      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
      "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
      "dependencies": {
        "hosted-git-info": "^2.1.4",
        "resolve": "^1.10.0",
        "semver": "2 || 3 || 4 || 5",
        "validate-npm-package-license": "^3.0.1"
      }
    },
    "node_modules/read-pkg/node_modules/semver": {
      "version": "5.7.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
      "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
      "bin": {
        "semver": "bin/semver"
      }
    },
    "node_modules/read-pkg/node_modules/type-fest": {
      "version": "0.6.0",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
      "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/readable-stream": {
      "version": "3.6.2",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
      "dependencies": {
        "inherits": "^2.0.3",
        "string_decoder": "^1.1.1",
        "util-deprecate": "^1.0.1"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/redent": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
      "dependencies": {
        "indent-string": "^4.0.0",
        "strip-indent": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/resolve": {
      "version": "1.22.2",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
      "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
      "dependencies": {
        "is-core-module": "^2.11.0",
        "path-parse": "^1.0.7",
        "supports-preserve-symlinks-flag": "^1.0.0"
      },
      "bin": {
        "resolve": "bin/resolve"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/retry": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
      "engines": {
        "node": ">= 4"
      }
    },
    "node_modules/rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "dependencies": {
        "glob": "^7.1.3"
      },
      "bin": {
        "rimraf": "bin.js"
      },
      "funding": {
        "url": "https://github.com/sponsors/isaacs"
      }
    },
    "node_modules/safe-buffer": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ]
    },
    "node_modules/safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "optional": true
    },
    "node_modules/sass-graph": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
      "dependencies": {
        "glob": "^7.0.0",
        "lodash": "^4.17.11",
        "scss-tokenizer": "^0.4.3",
        "yargs": "^17.2.1"
      },
      "bin": {
        "sassgraph": "bin/sassgraph"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/scss-tokenizer": {
      "version": "0.4.3",
      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
      "dependencies": {
        "js-base64": "^2.4.9",
        "source-map": "^0.7.3"
      }
    },
    "node_modules/semver": {
      "version": "7.5.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
      "dependencies": {
        "lru-cache": "^6.0.0"
      },
      "bin": {
        "semver": "bin/semver.js"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/semver/node_modules/lru-cache": {
      "version": "6.0.0",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
      "dependencies": {
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
    },
    "node_modules/shebang-command": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
      "dependencies": {
        "shebang-regex": "^3.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/shebang-regex": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/signal-exit": {
      "version": "3.0.7",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
    },
    "node_modules/smart-buffer": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
      "engines": {
        "node": ">= 6.0.0",
        "npm": ">= 3.0.0"
      }
    },
    "node_modules/socks": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
      "dependencies": {
        "ip": "^2.0.0",
        "smart-buffer": "^4.2.0"
      },
      "engines": {
        "node": ">= 10.13.0",
        "npm": ">= 3.0.0"
      }
    },
    "node_modules/socks-proxy-agent": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
      "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
      "dependencies": {
        "agent-base": "^6.0.2",
        "debug": "^4.3.3",
        "socks": "^2.6.2"
      },
      "engines": {
        "node": ">= 10"
      }
    },
    "node_modules/source-map": {
      "version": "0.7.4",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/spdx-correct": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
      "dependencies": {
        "spdx-expression-parse": "^3.0.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "node_modules/spdx-exceptions": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
    },
    "node_modules/spdx-expression-parse": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
      "dependencies": {
        "spdx-exceptions": "^2.1.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "node_modules/spdx-license-ids": {
      "version": "3.0.13",
      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
      "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w=="
    },
    "node_modules/ssri": {
      "version": "9.0.1",
      "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
      "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
      "dependencies": {
        "minipass": "^3.1.1"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/stdout-stream": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
      "dependencies": {
        "readable-stream": "^2.0.1"
      }
    },
    "node_modules/stdout-stream/node_modules/readable-stream": {
      "version": "2.3.8",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
      "dependencies": {
        "core-util-is": "~1.0.0",
        "inherits": "~2.0.3",
        "isarray": "~1.0.0",
        "process-nextick-args": "~2.0.0",
        "safe-buffer": "~5.1.1",
        "string_decoder": "~1.1.1",
        "util-deprecate": "~1.0.1"
      }
    },
    "node_modules/stdout-stream/node_modules/safe-buffer": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
    },
    "node_modules/stdout-stream/node_modules/string_decoder": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
      "dependencies": {
        "safe-buffer": "~5.1.0"
      }
    },
    "node_modules/string_decoder": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
      "dependencies": {
        "safe-buffer": "~5.2.0"
      }
    },
    "node_modules/string-width": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
      "dependencies": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/strip-ansi": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
      "dependencies": {
        "ansi-regex": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/strip-indent": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
      "dependencies": {
        "min-indent": "^1.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "dependencies": {
        "has-flag": "^4.0.0"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/supports-preserve-symlinks-flag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
      "engines": {
        "node": ">= 0.4"
      },
      "funding": {
        "url": "https://github.com/sponsors/ljharb"
      }
    },
    "node_modules/tar": {
      "version": "6.1.15",
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
      "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
      "dependencies": {
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "minipass": "^5.0.0",
        "minizlib": "^2.1.1",
        "mkdirp": "^1.0.3",
        "yallist": "^4.0.0"
      },
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/tar/node_modules/minipass": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
      "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/trim-newlines": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==",
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/true-case-path": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q=="
    },
    "node_modules/type-fest": {
      "version": "0.18.1",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==",
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/sponsors/sindresorhus"
      }
    },
    "node_modules/unique-filename": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
      "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
      "dependencies": {
        "unique-slug": "^3.0.0"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/unique-slug": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
      "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
      "dependencies": {
        "imurmurhash": "^0.1.4"
      },
      "engines": {
        "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
      }
    },
    "node_modules/util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
    },
    "node_modules/validate-npm-package-license": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
      "dependencies": {
        "spdx-correct": "^3.0.0",
        "spdx-expression-parse": "^3.0.0"
      }
    },
    "node_modules/which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "dependencies": {
        "isexe": "^2.0.0"
      },
      "bin": {
        "node-which": "bin/node-which"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/wide-align": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
      "dependencies": {
        "string-width": "^1.0.2 || 2 || 3 || 4"
      }
    },
    "node_modules/wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
      "dependencies": {
        "ansi-styles": "^4.0.0",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0"
      },
      "engines": {
        "node": ">=10"
      },
      "funding": {
        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
      }
    },
    "node_modules/wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
    },
    "node_modules/y18n": {
      "version": "5.0.8",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
    },
    "node_modules/yargs": {
      "version": "17.7.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
      "dependencies": {
        "cliui": "^8.0.1",
        "escalade": "^3.1.1",
        "get-caller-file": "^2.0.5",
        "require-directory": "^2.1.1",
        "string-width": "^4.2.3",
        "y18n": "^5.0.5",
        "yargs-parser": "^21.1.1"
      },
      "engines": {
        "node": ">=12"
      }
    },
    "node_modules/yargs-parser": {
      "version": "20.2.9",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
      "engines": {
        "node": ">=10"
      }
    },
    "node_modules/yargs/node_modules/yargs-parser": {
      "version": "21.1.1",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
      "engines": {
        "node": ">=12"
      }
    }
  },
  "dependencies": {
    "@babel/code-frame": {
      "version": "7.21.4",
      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.21.4.tgz",
      "integrity": "sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==",
      "requires": {
        "@babel/highlight": "^7.18.6"
      }
    },
    "@babel/helper-validator-identifier": {
      "version": "7.19.1",
      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz",
      "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w=="
    },
    "@babel/highlight": {
      "version": "7.18.6",
      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
      "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==",
      "requires": {
        "@babel/helper-validator-identifier": "^7.18.6",
        "chalk": "^2.0.0",
        "js-tokens": "^4.0.0"
      },
      "dependencies": {
        "ansi-styles": {
          "version": "3.2.1",
          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
          "requires": {
            "color-convert": "^1.9.0"
          }
        },
        "chalk": {
          "version": "2.4.2",
          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
          "requires": {
            "ansi-styles": "^3.2.1",
            "escape-string-regexp": "^1.0.5",
            "supports-color": "^5.3.0"
          }
        },
        "color-convert": {
          "version": "1.9.3",
          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
          "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
          "requires": {
            "color-name": "1.1.3"
          }
        },
        "color-name": {
          "version": "1.1.3",
          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
          "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
        },
        "has-flag": {
          "version": "3.0.0",
          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="
        },
        "supports-color": {
          "version": "5.5.0",
          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
          "requires": {
            "has-flag": "^3.0.0"
          }
        }
      }
    },
    "@gar/promisify": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
      "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="
    },
    "@npmcli/fs": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
      "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
      "requires": {
        "@gar/promisify": "^1.1.3",
        "semver": "^7.3.5"
      }
    },
    "@npmcli/move-file": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
      "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
      "requires": {
        "mkdirp": "^1.0.4",
        "rimraf": "^3.0.2"
      }
    },
    "@tootallnate/once": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="
    },
    "@types/minimist": {
      "version": "1.2.2",
      "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz",
      "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ=="
    },
    "@types/normalize-package-data": {
      "version": "2.4.1",
      "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz",
      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw=="
    },
    "abbrev": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
    },
    "agent-base": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
      "requires": {
        "debug": "4"
      }
    },
    "agentkeepalive": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz",
      "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==",
      "requires": {
        "debug": "^4.1.0",
        "depd": "^2.0.0",
        "humanize-ms": "^1.2.1"
      }
    },
    "aggregate-error": {
      "version": "3.1.0",
      "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
      "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
      "requires": {
        "clean-stack": "^2.0.0",
        "indent-string": "^4.0.0"
      }
    },
    "ansi-regex": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
    },
    "ansi-styles": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
      "requires": {
        "color-convert": "^2.0.1"
      }
    },
    "aproba": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz",
      "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
    },
    "are-we-there-yet": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz",
      "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==",
      "requires": {
        "delegates": "^1.0.0",
        "readable-stream": "^3.6.0"
      }
    },
    "arrify": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
      "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA=="
    },
    "async-foreach": {
      "version": "0.1.3",
      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
      "integrity": "sha512-VUeSMD8nEGBWaZK4lizI1sf3yEC7pnAQ/mrI7pC2fBz2s/tq5jWWEngTwaf0Gruu/OoXRGLGg1XFqpYBiGTYJA=="
    },
    "balanced-match": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
    },
    "brace-expansion": {
      "version": "1.1.11",
      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
      "requires": {
        "balanced-match": "^1.0.0",
        "concat-map": "0.0.1"
      }
    },
    "cacache": {
      "version": "16.1.3",
      "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
      "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
      "requires": {
        "@npmcli/fs": "^2.1.0",
        "@npmcli/move-file": "^2.0.0",
        "chownr": "^2.0.0",
        "fs-minipass": "^2.1.0",
        "glob": "^8.0.1",
        "infer-owner": "^1.0.4",
        "lru-cache": "^7.7.1",
        "minipass": "^3.1.6",
        "minipass-collect": "^1.0.2",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "mkdirp": "^1.0.4",
        "p-map": "^4.0.0",
        "promise-inflight": "^1.0.1",
        "rimraf": "^3.0.2",
        "ssri": "^9.0.0",
        "tar": "^6.1.11",
        "unique-filename": "^2.0.0"
      },
      "dependencies": {
        "brace-expansion": {
          "version": "2.0.1",
          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
          "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
          "requires": {
            "balanced-match": "^1.0.0"
          }
        },
        "glob": {
          "version": "8.1.0",
          "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
          "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
          "requires": {
            "fs.realpath": "^1.0.0",
            "inflight": "^1.0.4",
            "inherits": "2",
            "minimatch": "^5.0.1",
            "once": "^1.3.0"
          }
        },
        "minimatch": {
          "version": "5.1.6",
          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
          "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
          "requires": {
            "brace-expansion": "^2.0.1"
          }
        }
      }
    },
    "camelcase": {
      "version": "5.3.1",
      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
      "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="
    },
    "camelcase-keys": {
      "version": "6.2.2",
      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz",
      "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==",
      "requires": {
        "camelcase": "^5.3.1",
        "map-obj": "^4.0.0",
        "quick-lru": "^4.0.1"
      }
    },
    "chalk": {
      "version": "4.1.2",
      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
      "requires": {
        "ansi-styles": "^4.1.0",
        "supports-color": "^7.1.0"
      }
    },
    "chownr": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
      "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
    },
    "clean-stack": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
      "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="
    },
    "cliui": {
      "version": "8.0.1",
      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
      "requires": {
        "string-width": "^4.2.0",
        "strip-ansi": "^6.0.1",
        "wrap-ansi": "^7.0.0"
      }
    },
    "color-convert": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
      "requires": {
        "color-name": "~1.1.4"
      }
    },
    "color-name": {
      "version": "1.1.4",
      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
    },
    "color-support": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
    },
    "concat-map": {
      "version": "0.0.1",
      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
    },
    "console-control-strings": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
      "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="
    },
    "core-util-is": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
    },
    "cross-spawn": {
      "version": "7.0.3",
      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
      "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
      "requires": {
        "path-key": "^3.1.0",
        "shebang-command": "^2.0.0",
        "which": "^2.0.1"
      }
    },
    "debug": {
      "version": "4.3.4",
      "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
      "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
      "requires": {
        "ms": "2.1.2"
      }
    },
    "decamelize": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
      "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
    },
    "decamelize-keys": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz",
      "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==",
      "requires": {
        "decamelize": "^1.1.0",
        "map-obj": "^1.0.0"
      },
      "dependencies": {
        "map-obj": {
          "version": "1.0.1",
          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
          "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg=="
        }
      }
    },
    "delegates": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
      "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="
    },
    "depd": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
      "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
    },
    "emoji-regex": {
      "version": "8.0.0",
      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
    },
    "encoding": {
      "version": "0.1.13",
      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
      "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
      "optional": true,
      "requires": {
        "iconv-lite": "^0.6.2"
      }
    },
    "env-paths": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
      "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="
    },
    "err-code": {
      "version": "2.0.3",
      "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz",
      "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="
    },
    "error-ex": {
      "version": "1.3.2",
      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
      "requires": {
        "is-arrayish": "^0.2.1"
      }
    },
    "escalade": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
    },
    "escape-string-regexp": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
    },
    "find-up": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
      "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
      "requires": {
        "locate-path": "^5.0.0",
        "path-exists": "^4.0.0"
      }
    },
    "fs-minipass": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
      "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "fs.realpath": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
    },
    "function-bind": {
      "version": "1.1.1",
      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
    },
    "gauge": {
      "version": "4.0.4",
      "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz",
      "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==",
      "requires": {
        "aproba": "^1.0.3 || ^2.0.0",
        "color-support": "^1.1.3",
        "console-control-strings": "^1.1.0",
        "has-unicode": "^2.0.1",
        "signal-exit": "^3.0.7",
        "string-width": "^4.2.3",
        "strip-ansi": "^6.0.1",
        "wide-align": "^1.1.5"
      }
    },
    "gaze": {
      "version": "1.1.3",
      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
      "requires": {
        "globule": "^1.0.0"
      }
    },
    "get-caller-file": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
    },
    "get-stdin": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
      "integrity": "sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw=="
    },
    "glob": {
      "version": "7.2.3",
      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
      "requires": {
        "fs.realpath": "^1.0.0",
        "inflight": "^1.0.4",
        "inherits": "2",
        "minimatch": "^3.1.1",
        "once": "^1.3.0",
        "path-is-absolute": "^1.0.0"
      }
    },
    "globule": {
      "version": "1.3.4",
      "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
      "integrity": "sha512-OPTIfhMBh7JbBYDpa5b+Q5ptmMWKwcNcFSR/0c6t8V4f3ZAVBEsKNY37QdVqmLRYSMhOUGYrY0QhSoEpzGr/Eg==",
      "requires": {
        "glob": "~7.1.1",
        "lodash": "^4.17.21",
        "minimatch": "~3.0.2"
      },
      "dependencies": {
        "glob": {
          "version": "7.1.7",
          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
          "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
          "requires": {
            "fs.realpath": "^1.0.0",
            "inflight": "^1.0.4",
            "inherits": "2",
            "minimatch": "^3.0.4",
            "once": "^1.3.0",
            "path-is-absolute": "^1.0.0"
          }
        },
        "minimatch": {
          "version": "3.0.8",
          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
          "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
          "requires": {
            "brace-expansion": "^1.1.7"
          }
        }
      }
    },
    "graceful-fs": {
      "version": "4.2.11",
      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
      "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
    },
    "hard-rejection": {
      "version": "2.1.0",
      "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz",
      "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA=="
    },
    "has": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
      "requires": {
        "function-bind": "^1.1.1"
      }
    },
    "has-flag": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
    },
    "has-unicode": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
      "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="
    },
    "hosted-git-info": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
      "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
      "requires": {
        "lru-cache": "^6.0.0"
      },
      "dependencies": {
        "lru-cache": {
          "version": "6.0.0",
          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
          "requires": {
            "yallist": "^4.0.0"
          }
        }
      }
    },
    "http-cache-semantics": {
      "version": "4.1.1",
      "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
      "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
    },
    "http-proxy-agent": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
      "requires": {
        "@tootallnate/once": "2",
        "agent-base": "6",
        "debug": "4"
      }
    },
    "https-proxy-agent": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
      "requires": {
        "agent-base": "6",
        "debug": "4"
      }
    },
    "humanize-ms": {
      "version": "1.2.1",
      "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
      "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
      "requires": {
        "ms": "^2.0.0"
      }
    },
    "iconv-lite": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
      "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
      "optional": true,
      "requires": {
        "safer-buffer": ">= 2.1.2 < 3.0.0"
      }
    },
    "imurmurhash": {
      "version": "0.1.4",
      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
      "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
    },
    "indent-string": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
      "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="
    },
    "infer-owner": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
      "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
    },
    "inflight": {
      "version": "1.0.6",
      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
      "requires": {
        "once": "^1.3.0",
        "wrappy": "1"
      }
    },
    "inherits": {
      "version": "2.0.4",
      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
    },
    "ip": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
      "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ=="
    },
    "is-arrayish": {
      "version": "0.2.1",
      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
      "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
    },
    "is-core-module": {
      "version": "2.12.1",
      "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
      "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
      "requires": {
        "has": "^1.0.3"
      }
    },
    "is-fullwidth-code-point": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
    },
    "is-lambda": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz",
      "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="
    },
    "is-plain-obj": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
      "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg=="
    },
    "isarray": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
    },
    "isexe": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
      "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
    },
    "js-base64": {
      "version": "2.6.4",
      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz",
      "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ=="
    },
    "js-tokens": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
    },
    "json-parse-even-better-errors": {
      "version": "2.3.1",
      "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
      "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="
    },
    "kind-of": {
      "version": "6.0.3",
      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
      "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
    },
    "lines-and-columns": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
      "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="
    },
    "locate-path": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
      "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
      "requires": {
        "p-locate": "^4.1.0"
      }
    },
    "lodash": {
      "version": "4.17.21",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
    },
    "lru-cache": {
      "version": "7.18.3",
      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="
    },
    "make-fetch-happen": {
      "version": "10.2.1",
      "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz",
      "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==",
      "requires": {
        "agentkeepalive": "^4.2.1",
        "cacache": "^16.1.0",
        "http-cache-semantics": "^4.1.0",
        "http-proxy-agent": "^5.0.0",
        "https-proxy-agent": "^5.0.0",
        "is-lambda": "^1.0.1",
        "lru-cache": "^7.7.1",
        "minipass": "^3.1.6",
        "minipass-collect": "^1.0.2",
        "minipass-fetch": "^2.0.3",
        "minipass-flush": "^1.0.5",
        "minipass-pipeline": "^1.2.4",
        "negotiator": "^0.6.3",
        "promise-retry": "^2.0.1",
        "socks-proxy-agent": "^7.0.0",
        "ssri": "^9.0.0"
      }
    },
    "map-obj": {
      "version": "4.3.0",
      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz",
      "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ=="
    },
    "meow": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz",
      "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==",
      "requires": {
        "@types/minimist": "^1.2.0",
        "camelcase-keys": "^6.2.2",
        "decamelize": "^1.2.0",
        "decamelize-keys": "^1.1.0",
        "hard-rejection": "^2.1.0",
        "minimist-options": "4.1.0",
        "normalize-package-data": "^3.0.0",
        "read-pkg-up": "^7.0.1",
        "redent": "^3.0.0",
        "trim-newlines": "^3.0.0",
        "type-fest": "^0.18.0",
        "yargs-parser": "^20.2.3"
      }
    },
    "min-indent": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
      "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
    },
    "minimatch": {
      "version": "3.1.2",
      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
      "requires": {
        "brace-expansion": "^1.1.7"
      }
    },
    "minimist-options": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz",
      "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==",
      "requires": {
        "arrify": "^1.0.1",
        "is-plain-obj": "^1.1.0",
        "kind-of": "^6.0.3"
      }
    },
    "minipass": {
      "version": "3.3.6",
      "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
      "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
      "requires": {
        "yallist": "^4.0.0"
      }
    },
    "minipass-collect": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
      "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-fetch": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz",
      "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==",
      "requires": {
        "encoding": "^0.1.13",
        "minipass": "^3.1.6",
        "minipass-sized": "^1.0.3",
        "minizlib": "^2.1.2"
      }
    },
    "minipass-flush": {
      "version": "1.0.5",
      "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
      "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-pipeline": {
      "version": "1.2.4",
      "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
      "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minipass-sized": {
      "version": "1.0.3",
      "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz",
      "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==",
      "requires": {
        "minipass": "^3.0.0"
      }
    },
    "minizlib": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
      "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
      "requires": {
        "minipass": "^3.0.0",
        "yallist": "^4.0.0"
      }
    },
    "mkdirp": {
      "version": "1.0.4",
      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
      "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
    },
    "ms": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
    },
    "nan": {
      "version": "2.17.0",
      "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz",
      "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ=="
    },
    "negotiator": {
      "version": "0.6.3",
      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
      "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
    },
    "node-gyp": {
      "version": "8.4.1",
      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz",
      "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==",
      "requires": {
        "env-paths": "^2.2.0",
        "glob": "^7.1.4",
        "graceful-fs": "^4.2.6",
        "make-fetch-happen": "^9.1.0",
        "nopt": "^5.0.0",
        "npmlog": "^6.0.0",
        "rimraf": "^3.0.2",
        "semver": "^7.3.5",
        "tar": "^6.1.2",
        "which": "^2.0.2"
      },
      "dependencies": {
        "@npmcli/fs": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz",
          "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==",
          "requires": {
            "@gar/promisify": "^1.0.1",
            "semver": "^7.3.5"
          }
        },
        "@npmcli/move-file": {
          "version": "1.1.2",
          "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz",
          "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==",
          "requires": {
            "mkdirp": "^1.0.4",
            "rimraf": "^3.0.2"
          }
        },
        "@tootallnate/once": {
          "version": "1.1.2",
          "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
          "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="
        },
        "cacache": {
          "version": "15.3.0",
          "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz",
          "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==",
          "requires": {
            "@npmcli/fs": "^1.0.0",
            "@npmcli/move-file": "^1.0.1",
            "chownr": "^2.0.0",
            "fs-minipass": "^2.0.0",
            "glob": "^7.1.4",
            "infer-owner": "^1.0.4",
            "lru-cache": "^6.0.0",
            "minipass": "^3.1.1",
            "minipass-collect": "^1.0.2",
            "minipass-flush": "^1.0.5",
            "minipass-pipeline": "^1.2.2",
            "mkdirp": "^1.0.3",
            "p-map": "^4.0.0",
            "promise-inflight": "^1.0.1",
            "rimraf": "^3.0.2",
            "ssri": "^8.0.1",
            "tar": "^6.0.2",
            "unique-filename": "^1.1.1"
          }
        },
        "http-proxy-agent": {
          "version": "4.0.1",
          "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
          "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
          "requires": {
            "@tootallnate/once": "1",
            "agent-base": "6",
            "debug": "4"
          }
        },
        "lru-cache": {
          "version": "6.0.0",
          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
          "requires": {
            "yallist": "^4.0.0"
          }
        },
        "make-fetch-happen": {
          "version": "9.1.0",
          "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz",
          "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==",
          "requires": {
            "agentkeepalive": "^4.1.3",
            "cacache": "^15.2.0",
            "http-cache-semantics": "^4.1.0",
            "http-proxy-agent": "^4.0.1",
            "https-proxy-agent": "^5.0.0",
            "is-lambda": "^1.0.1",
            "lru-cache": "^6.0.0",
            "minipass": "^3.1.3",
            "minipass-collect": "^1.0.2",
            "minipass-fetch": "^1.3.2",
            "minipass-flush": "^1.0.5",
            "minipass-pipeline": "^1.2.4",
            "negotiator": "^0.6.2",
            "promise-retry": "^2.0.1",
            "socks-proxy-agent": "^6.0.0",
            "ssri": "^8.0.0"
          }
        },
        "minipass-fetch": {
          "version": "1.4.1",
          "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz",
          "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==",
          "requires": {
            "encoding": "^0.1.12",
            "minipass": "^3.1.0",
            "minipass-sized": "^1.0.3",
            "minizlib": "^2.0.0"
          }
        },
        "socks-proxy-agent": {
          "version": "6.2.1",
          "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz",
          "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==",
          "requires": {
            "agent-base": "^6.0.2",
            "debug": "^4.3.3",
            "socks": "^2.6.2"
          }
        },
        "ssri": {
          "version": "8.0.1",
          "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz",
          "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==",
          "requires": {
            "minipass": "^3.1.1"
          }
        },
        "unique-filename": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz",
          "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==",
          "requires": {
            "unique-slug": "^2.0.0"
          }
        },
        "unique-slug": {
          "version": "2.0.2",
          "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz",
          "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==",
          "requires": {
            "imurmurhash": "^0.1.4"
          }
        }
      }
    },
    "node-sass": {
      "version": "9.0.0",
      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-9.0.0.tgz",
      "integrity": "sha512-yltEuuLrfH6M7Pq2gAj5B6Zm7m+gdZoG66wTqG6mIZV/zijq3M2OO2HswtT6oBspPyFhHDcaxWpsBm0fRNDHPg==",
      "requires": {
        "async-foreach": "^0.1.3",
        "chalk": "^4.1.2",
        "cross-spawn": "^7.0.3",
        "gaze": "^1.0.0",
        "get-stdin": "^4.0.1",
        "glob": "^7.0.3",
        "lodash": "^4.17.15",
        "make-fetch-happen": "^10.0.4",
        "meow": "^9.0.0",
        "nan": "^2.17.0",
        "node-gyp": "^8.4.1",
        "sass-graph": "^4.0.1",
        "stdout-stream": "^1.4.0",
        "true-case-path": "^2.2.1"
      }
    },
    "nopt": {
      "version": "5.0.0",
      "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
      "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==",
      "requires": {
        "abbrev": "1"
      }
    },
    "normalize-package-data": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz",
      "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==",
      "requires": {
        "hosted-git-info": "^4.0.1",
        "is-core-module": "^2.5.0",
        "semver": "^7.3.4",
        "validate-npm-package-license": "^3.0.1"
      }
    },
    "npmlog": {
      "version": "6.0.2",
      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz",
      "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==",
      "requires": {
        "are-we-there-yet": "^3.0.0",
        "console-control-strings": "^1.1.0",
        "gauge": "^4.0.3",
        "set-blocking": "^2.0.0"
      }
    },
    "once": {
      "version": "1.4.0",
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
      "requires": {
        "wrappy": "1"
      }
    },
    "p-limit": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
      "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
      "requires": {
        "p-try": "^2.0.0"
      }
    },
    "p-locate": {
      "version": "4.1.0",
      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
      "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
      "requires": {
        "p-limit": "^2.2.0"
      }
    },
    "p-map": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
      "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
      "requires": {
        "aggregate-error": "^3.0.0"
      }
    },
    "p-try": {
      "version": "2.2.0",
      "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
      "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="
    },
    "parse-json": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
      "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
      "requires": {
        "@babel/code-frame": "^7.0.0",
        "error-ex": "^1.3.1",
        "json-parse-even-better-errors": "^2.3.0",
        "lines-and-columns": "^1.1.6"
      }
    },
    "path-exists": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
    },
    "path-is-absolute": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
    },
    "path-key": {
      "version": "3.1.1",
      "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
      "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
    },
    "path-parse": {
      "version": "1.0.7",
      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
      "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
    },
    "process-nextick-args": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
    },
    "promise-inflight": {
      "version": "1.0.1",
      "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
      "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="
    },
    "promise-retry": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz",
      "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==",
      "requires": {
        "err-code": "^2.0.2",
        "retry": "^0.12.0"
      }
    },
    "quick-lru": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz",
      "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g=="
    },
    "read-pkg": {
      "version": "5.2.0",
      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz",
      "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==",
      "requires": {
        "@types/normalize-package-data": "^2.4.0",
        "normalize-package-data": "^2.5.0",
        "parse-json": "^5.0.0",
        "type-fest": "^0.6.0"
      },
      "dependencies": {
        "hosted-git-info": {
          "version": "2.8.9",
          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
          "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
        },
        "normalize-package-data": {
          "version": "2.5.0",
          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
          "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
          "requires": {
            "hosted-git-info": "^2.1.4",
            "resolve": "^1.10.0",
            "semver": "2 || 3 || 4 || 5",
            "validate-npm-package-license": "^3.0.1"
          }
        },
        "semver": {
          "version": "5.7.1",
          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
        },
        "type-fest": {
          "version": "0.6.0",
          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz",
          "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg=="
        }
      }
    },
    "read-pkg-up": {
      "version": "7.0.1",
      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz",
      "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==",
      "requires": {
        "find-up": "^4.1.0",
        "read-pkg": "^5.2.0",
        "type-fest": "^0.8.1"
      },
      "dependencies": {
        "type-fest": {
          "version": "0.8.1",
          "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
          "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA=="
        }
      }
    },
    "readable-stream": {
      "version": "3.6.2",
      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
      "requires": {
        "inherits": "^2.0.3",
        "string_decoder": "^1.1.1",
        "util-deprecate": "^1.0.1"
      }
    },
    "redent": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz",
      "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==",
      "requires": {
        "indent-string": "^4.0.0",
        "strip-indent": "^3.0.0"
      }
    },
    "require-directory": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
    },
    "resolve": {
      "version": "1.22.2",
      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
      "integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
      "requires": {
        "is-core-module": "^2.11.0",
        "path-parse": "^1.0.7",
        "supports-preserve-symlinks-flag": "^1.0.0"
      }
    },
    "retry": {
      "version": "0.12.0",
      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="
    },
    "rimraf": {
      "version": "3.0.2",
      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
      "requires": {
        "glob": "^7.1.3"
      }
    },
    "safe-buffer": {
      "version": "5.2.1",
      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
    },
    "safer-buffer": {
      "version": "2.1.2",
      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
      "optional": true
    },
    "sass-graph": {
      "version": "4.0.1",
      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-4.0.1.tgz",
      "integrity": "sha512-5YCfmGBmxoIRYHnKK2AKzrAkCoQ8ozO+iumT8K4tXJXRVCPf+7s1/9KxTSW3Rbvf+7Y7b4FR3mWyLnQr3PHocA==",
      "requires": {
        "glob": "^7.0.0",
        "lodash": "^4.17.11",
        "scss-tokenizer": "^0.4.3",
        "yargs": "^17.2.1"
      }
    },
    "scss-tokenizer": {
      "version": "0.4.3",
      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.4.3.tgz",
      "integrity": "sha512-raKLgf1LI5QMQnG+RxHz6oK0sL3x3I4FN2UDLqgLOGO8hodECNnNh5BXn7fAyBxrA8zVzdQizQ6XjNJQ+uBwMw==",
      "requires": {
        "js-base64": "^2.4.9",
        "source-map": "^0.7.3"
      }
    },
    "semver": {
      "version": "7.5.1",
      "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.1.tgz",
      "integrity": "sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==",
      "requires": {
        "lru-cache": "^6.0.0"
      },
      "dependencies": {
        "lru-cache": {
          "version": "6.0.0",
          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
          "requires": {
            "yallist": "^4.0.0"
          }
        }
      }
    },
    "set-blocking": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
      "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
    },
    "shebang-command": {
      "version": "2.0.0",
      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
      "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
      "requires": {
        "shebang-regex": "^3.0.0"
      }
    },
    "shebang-regex": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
      "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
    },
    "signal-exit": {
      "version": "3.0.7",
      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
    },
    "smart-buffer": {
      "version": "4.2.0",
      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="
    },
    "socks": {
      "version": "2.7.1",
      "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz",
      "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==",
      "requires": {
        "ip": "^2.0.0",
        "smart-buffer": "^4.2.0"
      }
    },
    "socks-proxy-agent": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz",
      "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==",
      "requires": {
        "agent-base": "^6.0.2",
        "debug": "^4.3.3",
        "socks": "^2.6.2"
      }
    },
    "source-map": {
      "version": "0.7.4",
      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz",
      "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA=="
    },
    "spdx-correct": {
      "version": "3.2.0",
      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
      "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
      "requires": {
        "spdx-expression-parse": "^3.0.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "spdx-exceptions": {
      "version": "2.3.0",
      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
      "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
    },
    "spdx-expression-parse": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
      "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
      "requires": {
        "spdx-exceptions": "^2.1.0",
        "spdx-license-ids": "^3.0.0"
      }
    },
    "spdx-license-ids": {
      "version": "3.0.13",
      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz",
      "integrity": "sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w=="
    },
    "ssri": {
      "version": "9.0.1",
      "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
      "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
      "requires": {
        "minipass": "^3.1.1"
      }
    },
    "stdout-stream": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
      "requires": {
        "readable-stream": "^2.0.1"
      },
      "dependencies": {
        "readable-stream": {
          "version": "2.3.8",
          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
          "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
          "requires": {
            "core-util-is": "~1.0.0",
            "inherits": "~2.0.3",
            "isarray": "~1.0.0",
            "process-nextick-args": "~2.0.0",
            "safe-buffer": "~5.1.1",
            "string_decoder": "~1.1.1",
            "util-deprecate": "~1.0.1"
          }
        },
        "safe-buffer": {
          "version": "5.1.2",
          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
        },
        "string_decoder": {
          "version": "1.1.1",
          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
          "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
          "requires": {
            "safe-buffer": "~5.1.0"
          }
        }
      }
    },
    "string_decoder": {
      "version": "1.3.0",
      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
      "requires": {
        "safe-buffer": "~5.2.0"
      }
    },
    "string-width": {
      "version": "4.2.3",
      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
      "requires": {
        "emoji-regex": "^8.0.0",
        "is-fullwidth-code-point": "^3.0.0",
        "strip-ansi": "^6.0.1"
      }
    },
    "strip-ansi": {
      "version": "6.0.1",
      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
      "requires": {
        "ansi-regex": "^5.0.1"
      }
    },
    "strip-indent": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz",
      "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==",
      "requires": {
        "min-indent": "^1.0.0"
      }
    },
    "supports-color": {
      "version": "7.2.0",
      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
      "requires": {
        "has-flag": "^4.0.0"
      }
    },
    "supports-preserve-symlinks-flag": {
      "version": "1.0.0",
      "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
      "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
    },
    "tar": {
      "version": "6.1.15",
      "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz",
      "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==",
      "requires": {
        "chownr": "^2.0.0",
        "fs-minipass": "^2.0.0",
        "minipass": "^5.0.0",
        "minizlib": "^2.1.1",
        "mkdirp": "^1.0.3",
        "yallist": "^4.0.0"
      },
      "dependencies": {
        "minipass": {
          "version": "5.0.0",
          "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
          "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="
        }
      }
    },
    "trim-newlines": {
      "version": "3.0.1",
      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz",
      "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw=="
    },
    "true-case-path": {
      "version": "2.2.1",
      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-2.2.1.tgz",
      "integrity": "sha512-0z3j8R7MCjy10kc/g+qg7Ln3alJTodw9aDuVWZa3uiWqfuBMKeAeP2ocWcxoyM3D73yz3Jt/Pu4qPr4wHSdB/Q=="
    },
    "type-fest": {
      "version": "0.18.1",
      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz",
      "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw=="
    },
    "unique-filename": {
      "version": "2.0.1",
      "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
      "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
      "requires": {
        "unique-slug": "^3.0.0"
      }
    },
    "unique-slug": {
      "version": "3.0.0",
      "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
      "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
      "requires": {
        "imurmurhash": "^0.1.4"
      }
    },
    "util-deprecate": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
    },
    "validate-npm-package-license": {
      "version": "3.0.4",
      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
      "requires": {
        "spdx-correct": "^3.0.0",
        "spdx-expression-parse": "^3.0.0"
      }
    },
    "which": {
      "version": "2.0.2",
      "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
      "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
      "requires": {
        "isexe": "^2.0.0"
      }
    },
    "wide-align": {
      "version": "1.1.5",
      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz",
      "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==",
      "requires": {
        "string-width": "^1.0.2 || 2 || 3 || 4"
      }
    },
    "wrap-ansi": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
      "requires": {
        "ansi-styles": "^4.0.0",
        "string-width": "^4.1.0",
        "strip-ansi": "^6.0.0"
      }
    },
    "wrappy": {
      "version": "1.0.2",
      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
      "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
    },
    "y18n": {
      "version": "5.0.8",
      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="
    },
    "yallist": {
      "version": "4.0.0",
      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
    },
    "yargs": {
      "version": "17.7.2",
      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
      "requires": {
        "cliui": "^8.0.1",
        "escalade": "^3.1.1",
        "get-caller-file": "^2.0.5",
        "require-directory": "^2.1.1",
        "string-width": "^4.2.3",
        "y18n": "^5.0.5",
        "yargs-parser": "^21.1.1"
      },
      "dependencies": {
        "yargs-parser": {
          "version": "21.1.1",
          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
          "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
        }
      }
    },
    "yargs-parser": {
      "version": "20.2.9",
      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
      "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w=="
    }
  }
}
package.json
New file
@@ -0,0 +1,5 @@
{
  "dependencies": {
    "node-sass": "^9.0.0"
  }
}
pom.xml
New file
@@ -0,0 +1,312 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan</artifactId>
    <version>3.6.2</version>
    <name>xinquan</name>
    <url>http://www.xinquan.vip</url>
    <description>心泉·冥想</description>
    <properties>
        <xinquan.version>3.6.2</xinquan.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-boot.version>2.7.7</spring-boot.version>
        <spring-cloud.version>2021.0.5</spring-cloud.version>
        <spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version>
        <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
        <swagger.fox.version>3.0.0</swagger.fox.version>
        <swagger.core.version>1.6.2</swagger.core.version>
        <tobato.version>1.27.2</tobato.version>
        <kaptcha.version>2.3.3</kaptcha.version>
        <pagehelper.boot.version>1.4.6</pagehelper.boot.version>
        <druid.version>1.2.16</druid.version>
        <dynamic-ds.version>3.5.2</dynamic-ds.version>
        <commons.io.version>2.11.0</commons.io.version>
        <velocity.version>2.3</velocity.version>
        <fastjson.version>2.0.25</fastjson.version>
        <jjwt.version>0.9.1</jjwt.version>
        <minio.version>8.2.2</minio.version>
        <poi.version>4.1.2</poi.version>
        <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
        <knife4j.version>3.0.3</knife4j.version>
        <hutool.version>5.7.17</hutool.version>
    </properties>
    <!-- 依赖声明 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringCloud 微服务 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringCloud Alibaba 微服务 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringBoot 依赖配置 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- FastDFS 分布式文件系统 -->
            <dependency>
                <groupId>com.github.tobato</groupId>
                <artifactId>fastdfs-client</artifactId>
                <version>${tobato.version}</version>
            </dependency>
            <!-- Swagger 依赖配置 -->
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-models</artifactId>
                <version>${swagger.core.version}</version>
            </dependency>
            <dependency>
                <groupId>io.swagger</groupId>
                <artifactId>swagger-annotations</artifactId>
                <version>${swagger.core.version}</version>
            </dependency>
            <!-- 验证码 -->
            <dependency>
                <groupId>pro.fessional</groupId>
                <artifactId>kaptcha</artifactId>
                <version>${kaptcha.version}</version>
            </dependency>
            <!-- pagehelper 分页插件 -->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.boot.version}</version>
            </dependency>
            <!-- io常用工具类 -->
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons.io.version}</version>
            </dependency>
            <!-- excel工具 -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>${poi.version}</version>
            </dependency>
            <!-- 代码生成使用模板 -->
            <dependency>
                <groupId>org.apache.velocity</groupId>
                <artifactId>velocity-engine-core</artifactId>
                <version>${velocity.version}</version>
            </dependency>
            <!-- JSON 解析器和生成器 -->
            <dependency>
                <groupId>com.alibaba.fastjson2</groupId>
                <artifactId>fastjson2</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <!-- JWT -->
            <dependency>
                <groupId>io.jsonwebtoken</groupId>
                <artifactId>jjwt</artifactId>
                <version>${jjwt.version}</version>
            </dependency>
            <!-- 线程传递值 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>transmittable-thread-local</artifactId>
                <version>${transmittable-thread-local.version}</version>
            </dependency>
            <!-- 核心模块 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-core</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 接口模块 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-swagger</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 安全模块 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-security</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 权限范围 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-datascope</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 多数据源 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-datasource</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 分布式事务 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-seata</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 日志记录 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-log</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 缓存服务 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-common-redis</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- 系统接口 -->
            <dependency>
                <groupId>com.xinquan</groupId>
                <artifactId>xinquan-api-system</artifactId>
                <version>${xinquan.version}</version>
            </dependency>
            <!-- swagger增强配置 knife4j -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
            </dependency>
            <!--knife4j的UI-->
            <!-- https://mvnrepository.com/artifact/com.github.xiaoymin/knife4j-micro-spring-boot-starter -->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-micro-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
            </dependency>
            <!--hutool工具包-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <modules>
        <module>xinquan-auth</module>
        <module>xinquan-gateway</module>
        <module>xinquan-visual</module>
        <module>xinquan-modules</module>
        <module>xinquan-api</module>
        <module>xinquan-common</module>
        <module>xinquan-modules/xinquan-user</module>
        <module>xinquan-modules/xinquan-course</module>
        <module>xinquan-modules/xinquan-meditation</module>
        <module>xinquan-modules/xinquan-order</module>
    </modules>
    <packaging>pom</packaging>
    <dependencies>
        <!-- bootstrap 启动器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <version>${spring-boot.version}</version>
                    <executions>
                        <execution>
                            <goals>
                                <goal>repackage</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
    <repositories>
        <repository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>public</id>
            <name>aliyun nexus</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>
sql/quartz.sql
New file
@@ -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;
sql/ry_20230223.sql
New file
@@ -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 = '代码生成业务表字段';
sql/ry_config_20220929.sql
New file
@@ -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,'xinquan-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: xinquan-auth\n          uri: lb://xinquan-auth\n          predicates:\n            - Path=/auth/**\n          filters:\n            # 验证码处理\n            - CacheRequestFilter\n            - ValidateCodeFilter\n            - StripPrefix=1\n        # 代码生成\n        - id: xinquan-gen\n          uri: lb://xinquan-gen\n          predicates:\n            - Path=/code/**\n          filters:\n            - StripPrefix=1\n        # 定时任务\n        - id: xinquan-job\n          uri: lb://xinquan-job\n          predicates:\n            - Path=/schedule/**\n          filters:\n            - StripPrefix=1\n        # 系统模块\n        - id: xinquan-system\n          uri: lb://xinquan-system\n          predicates:\n            - Path=/system/**\n          filters:\n            - StripPrefix=1\n        # 文件服务\n        - id: xinquan-file\n          uri: lb://xinquan-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,'xinquan-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,'xinquan-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,'xinquan-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.xinquan.car\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,'xinquan-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.xinquan.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.xinquan.car\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,'xinquan-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.xinquan.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,'xinquan-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-xinquan-gateway','DEFAULT_GROUP','[\r\n    {\r\n        \"resource\": \"xinquan-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\": \"xinquan-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\": \"xinquan-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\": \"xinquan-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');
sql/ry_seata_20210128.sql
New file
@@ -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';
xinquan-api/pom.xml
New file
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xinquan</groupId>
        <artifactId>xinquan</artifactId>
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>xinquan-api-system</module>
        <module>xinquan-api-user</module>
        <module>xinquan-api-meditation</module>
        <module>xinquan-api-course</module>
        <module>xinquan-api-order</module>
    </modules>
    <artifactId>xinquan-api</artifactId>
    <packaging>pom</packaging>
    <description>
        xinquan-api系统接口
    </description>
</project>
xinquan-api/xinquan-api-course/pom.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan-api</artifactId>
    <version>3.6.2</version>
  </parent>
  <artifactId>xinquan-api-course</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies> <!-- RuoYi Common Core-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-common-core</artifactId>
      <exclusions>
        <exclusion>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper-spring-boot-starter</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/factory/RemoteCourseFallbackFactory.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.course.api.factory;
import com.xinquan.course.api.feign.RemoteCourseService;
import org.springframework.cloud.openfeign.FallbackFactory;
/**
 * @author mitao
 * @date 2024/8/21
 */
public class RemoteCourseFallbackFactory implements FallbackFactory<RemoteCourseService> {
    @Override
    public RemoteCourseService create(Throwable cause) {
        return null;
    }
}
xinquan-api/xinquan-api-course/src/main/java/com/xinquan/course/api/feign/RemoteCourseService.java
New file
@@ -0,0 +1,14 @@
package com.xinquan.course.api.feign;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.course.api.factory.RemoteCourseFallbackFactory;
import org.springframework.cloud.openfeign.FeignClient;
/**
 * @author mitao
 * @date 2024/8/21
 */
@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.COURSE, fallbackFactory = RemoteCourseFallbackFactory.class)
public interface RemoteCourseService {
}
xinquan-api/xinquan-api-course/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
New file
@@ -0,0 +1 @@
com.xinquan.course.api.factory.RemoteCourseFallbackFactory
xinquan-api/xinquan-api-meditation/pom.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan-api</artifactId>
    <version>3.6.2</version>
  </parent>
  <artifactId>xinquan-api-meditation</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies> <!-- RuoYi Common Core-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-common-core</artifactId>
      <exclusions>
        <exclusion>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper-spring-boot-starter</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>
xinquan-api/xinquan-api-meditation/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
xinquan-api/xinquan-api-order/pom.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan-api</artifactId>
    <version>3.6.2</version>
  </parent>
  <artifactId>xinquan-api-order</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies> <!-- RuoYi Common Core-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-common-core</artifactId>
      <exclusions>
        <exclusion>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper-spring-boot-starter</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>
xinquan-api/xinquan-api-order/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
xinquan-api/xinquan-api-system/pom.xml
New file
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xinquan</groupId>
        <artifactId>xinquan-api</artifactId>
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>xinquan-api-system</artifactId>
    <description>
        xinquan-api-system系统接口模块
    </description>
    <dependencies>
        <!-- RuoYi Common Core-->
        <dependency>
            <groupId>com.xinquan</groupId>
            <artifactId>xinquan-common-core</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>com.github.pagehelper</groupId>
                    <artifactId>pagehelper-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteFileService.java
New file
@@ -0,0 +1,29 @@
package com.xinquan.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.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.SysFile;
import com.xinquan.system.api.factory.RemoteFileFallbackFactory;
/**
 * 文件服务
 *
 * @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<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteLogService.java
New file
@@ -0,0 +1,41 @@
package com.xinquan.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.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.SysLogininfor;
import com.xinquan.system.api.domain.SysOperLog;
import com.xinquan.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<Boolean> saveLog(@RequestBody SysOperLog sysOperLog, @RequestHeader(SecurityConstants.FROM_SOURCE) String source) throws Exception;
    /**
     * 保存访问记录
     *
     * @param sysLogininfor 访问实体
     * @param source 请求来源
     * @return 结果
     */
    @PostMapping("/logininfor")
    public R<Boolean> saveLogininfor(@RequestBody SysLogininfor sysLogininfor, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/RemoteUserService.java
New file
@@ -0,0 +1,52 @@
package com.xinquan.system.api;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.factory.RemoteUserFallbackFactory;
import com.xinquan.system.api.model.LoginUser;
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;
/**
 * 用户服务
 *
 * @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<LoginUser> getUserInfo(@PathVariable("username") String username, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 注册用户信息
     *
     * @param sysUser 用户信息
     * @param source 请求来源
     * @return 结果
     */
    @PostMapping("/user/register")
    public R<Boolean> registerUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * 注册用户信息
     *
     * @param sysUser 用户信息
     * @param source 请求来源
     * @return 结果
     */
    @PostMapping("/user/app-register")
    public R<SysUser> registerAppUserInfo(@RequestBody SysUser sysUser, @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/DataUpdateHandlerConfig.java
New file
@@ -0,0 +1,36 @@
package com.xinquan.system.api.config;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.xinquan.system.api.model.LoginUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import java.util.Date;
/**
 * @author xiaochen
 * @ClassName DataUpdateInterceptor
 * @Description 数据更新操作处理
 * @date 2021-12-15
 * <p>
 * 注意,之前在此处注入了 JwtTokenUtils
 * <p>
 * 造成spring循环依赖,项目支棱不起来
 */
@Slf4j
@Configuration
public class DataUpdateHandlerConfig implements MetaObjectHandler {
    @Override
    public void insertFill(MetaObject metaObject) {
    }
    @Override
    public void updateFill(MetaObject metaObject) {
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/HttpConfig.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.system.api.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
 * http请求工具配置
 *
 * @author: KingKong
 * @create: 2018-11-14 10:47
 **/
@Configuration
public class HttpConfig {
    @Autowired
    private RestTemplateBuilder builder;
    @Bean
    public RestTemplate restTemplate() {
        return builder.build();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/config/MybatisPlusConfig.java
New file
@@ -0,0 +1,51 @@
package com.xinquan.system.api.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.config.GlobalConfig;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * @author xiaochen
 * @ClassName MybatisPlusConfig
 * @Description MybatisPlus相关配置
 * @date 2020-09-22 11:22、
 * 直接以实现类作为bean的注入(有事务管理的类)
 * @EnableTransactionManagement(proxyTargetClass = true)
 */
@Configuration
public class MybatisPlusConfig {
    private final DataUpdateHandlerConfig dataUpdateHandler;
    @Autowired
    public MybatisPlusConfig(DataUpdateHandlerConfig dataUpdateHandler) {
        this.dataUpdateHandler = dataUpdateHandler;
    }
    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,需要设置 MybatisConfiguration#useDeprecatedExecutor = false 避免缓存出现问题
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
    /**
     * 自动填充功能
     *
     * @return
     */
    @Bean
    public GlobalConfig globalConfig() {
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setMetaObjectHandler(dataUpdateHandler);
        return globalConfig;
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDept.java
New file
@@ -0,0 +1,201 @@
package com.xinquan.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.xinquan.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<SysDept> children = new ArrayList<SysDept>();
    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;
    }
    @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
    public String getDeptName()
    {
        return deptName;
    }
    public void setDeptName(String deptName)
    {
        this.deptName = deptName;
    }
    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<SysDept> getChildren()
    {
        return children;
    }
    public void setChildren(List<SysDept> 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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDictData.java
New file
@@ -0,0 +1,176 @@
package com.xinquan.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.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.common.core.constant.UserConstants;
import com.xinquan.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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysDictType.java
New file
@@ -0,0 +1,96 @@
package com.xinquan.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.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysFile.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysLogininfor.java
New file
@@ -0,0 +1,102 @@
package com.xinquan.system.api.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.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;
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysOperLog.java
New file
@@ -0,0 +1,255 @@
package com.xinquan.system.api.domain;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.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;
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysRole.java
New file
@@ -0,0 +1,256 @@
package com.xinquan.system.api.domain;
import java.util.Set;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.baomidou.mybatisplus.annotation.TableField;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.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)
    @TableField("role_id")
    private Long roleId;
    /** 角色名称 */
    @Excel(name = "角色名称")
    @TableField("role_name")
    private String roleName;
    /** 角色权限 */
    @Excel(name = "角色权限")
    @TableField("role_key")
    private String roleKey;
    /** 角色排序 */
    @Excel(name = "角色排序")
    @TableField("role_sort")
    private Integer roleSort;
    /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
    @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
    @TableField("data_scope")
    private String dataScope;
    /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
    @TableField("menu_check_strictly")
    private boolean menuCheckStrictly;
    /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
    @TableField("dept_check_strictly")
    private boolean deptCheckStrictly;
    /** 角色状态(0正常 1停用) */
    @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** 删除标志(0代表存在 2代表删除) */
    @TableField("del_flag")
    private String delFlag;
    /** 用户是否存在此角色标识 默认不存在 */
    @TableField(exist = false)
    private boolean flag = false;
    /** 菜单组 */
    @TableField(exist = false)
    private Long[] menuIds;
    /** 部门组(数据权限) */
    @TableField(exist = false)
    private Long[] deptIds;
    /** 角色菜单权限 */
    @TableField(exist = false)
    private Set<String> 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<String> getPermissions()
    {
        return permissions;
    }
    public void setPermissions(Set<String> 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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/domain/SysUser.java
New file
@@ -0,0 +1,356 @@
package com.xinquan.system.api.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.common.core.annotation.Excel.Type;
import com.xinquan.common.core.annotation.Excels;
import com.xinquan.common.core.web.domain.BaseEntity;
import com.xinquan.common.core.xss.Xss;
import io.swagger.annotations.ApiModelProperty;
import java.util.Date;
import java.util.List;
import javax.validation.constraints.Email;
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 org.springframework.format.annotation.DateTimeFormat;
/**
 * 用户对象 sys_user
 *
 * @author ruoyi
 */
public class SysUser extends BaseEntity
{
    private static final long serialVersionUID = 1L;
    /** 用户ID */
    @Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
    @TableField("user_id")
    private Long userId;
    /** 部门ID */
    @Excel(name = "部门编号", type = Type.IMPORT)
    @TableField("dept_id")
    private Long deptId;
    /** 用户账号 */
    @Excel(name = "登录名称")
    @TableField("user_name")
    private String userName;
    /** 用户昵称 */
    @Excel(name = "用户名称")
    @NotBlank(message = "姓名不能为空")
    @TableField("nick_name")
    private String nickName;
    /** 用户邮箱 */
    @Excel(name = "用户邮箱")
    private String email;
    /** 手机号码 */
    @Excel(name = "手机号码")
    @NotBlank(message = "请输入账号")
    private String phonenumber;
    /** 用户性别 */
    @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
    private String sex;
    /** 用户头像 */
    private String avatar;
    /** 密码 */
    @NotBlank(message = "密码不能为空")
    private String password;
    /** 帐号状态(0正常 1停用) */
    @Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
    private String status;
    /** 删除标志(0代表存在 2代表删除) */
    @TableField("del_flag")
    private String delFlag;
    /** 最后登录IP */
    @Excel(name = "最后登录IP", type = Type.EXPORT)
    @TableField("login_ip")
    private String loginIp;
    /** 最后登录时间 */
    @Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    @TableField("login_date")
    private Date loginDate;
    /** 部门对象 */
    @Excels({
        @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
        @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
    })
    @TableField(exist = false)
    private SysDept dept;
    /** 角色对象 */
    @TableField(exist = false)
    private List<SysRole> roles;
    /** 角色组 */
    @TableField(exist = false)
    private Long[] roleIds;
    /** 岗位组 */
    @TableField(exist = false)
    private Long[] postIds;
    /** 角色ID */
    @TableField(exist = false)
    private Long roleId;
    @ApiModelProperty(value = "备注")
    private String remark;
    @Override
    public String getRemark() {
        return remark;
    }
    @Override
    public void setRemark(String remark) {
        this.remark = remark;
    }
    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 = "用户账号不能包含脚本字符")
    @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<SysRole> getRoles()
    {
        return roles;
    }
    public void setRoles(List<SysRole> 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();
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteFileFallbackFactory.java
New file
@@ -0,0 +1,35 @@
package com.xinquan.system.api.factory;
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.xinquan.common.core.domain.R;
import com.xinquan.system.api.RemoteFileService;
import com.xinquan.system.api.domain.SysFile;
/**
 * 文件服务降级处理
 *
 * @author ruoyi
 */
@Component
public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
{
    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<SysFile> upload(MultipartFile file)
            {
                return R.fail("上传文件失败:" + throwable.getMessage());
            }
        };
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteLogFallbackFactory.java
New file
@@ -0,0 +1,42 @@
package com.xinquan.system.api.factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.RemoteLogService;
import com.xinquan.system.api.domain.SysLogininfor;
import com.xinquan.system.api.domain.SysOperLog;
/**
 * 日志服务降级处理
 *
 * @author ruoyi
 */
@Component
public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogService>
{
    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<Boolean> saveLog(SysOperLog sysOperLog, String source)
            {
                return null;
            }
            @Override
            public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
            {
                return null;
            }
        };
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/RemoteUserFallbackFactory.java
New file
@@ -0,0 +1,45 @@
package com.xinquan.system.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.model.LoginUser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
 * 用户服务降级处理
 *
 * @author ruoyi
 */
@Component
public class RemoteUserFallbackFactory implements FallbackFactory<RemoteUserService>
{
    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<LoginUser> getUserInfo(String username, String source)
            {
                return R.fail("获取用户失败:" + throwable.getMessage());
            }
            @Override
            public R<Boolean> registerUserInfo(SysUser sysUser, String source)
            {
                return R.fail("注册用户失败:" + throwable.getMessage());
            }
            @Override
            public R<SysUser> registerAppUserInfo(SysUser sysUser, String source) {
                return R.fail("注册APP用户失败:" + throwable.getMessage());
            }
        };
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/factory/SysUserFallbackFactory.java
New file
@@ -0,0 +1,69 @@
package com.xinquan.system.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.*;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class SysUserFallbackFactory implements FallbackFactory<SysUserClient> {
    @Override
    public SysUserClient create(Throwable cause) {
        return new SysUserClient(){
            @Override
            public R<SysUser> getSysUser(Long userId) {
                return R.fail("获取用户失败:" + cause.getMessage());
            }
            @Override
            public R<Boolean> updateSysUser(SysUser sysUser) {
                return R.fail("更新用户失败:" + cause.getMessage());
            }
            @Override
            public R<List<SysUser>> getUserList(List<Integer> userIds) {
                return R.fail("通过用户id集合查询用户失败:" + cause.getMessage());
            }
            @Override
            public R<Boolean> updateUser(SysUser sysUser) {
                return R.fail("修改用户信息失败:" + cause.getMessage());
            }
            @Override
            public R<SysRole> queryRoleByUserId(Long userId) {
                return R.fail("通过用户id查询角色对象失败:" + cause.getMessage());
            }
            @Override
            public R<SysRole> queryRoleByRoleId(Long roleId) {
                return R.fail("通过角色id查询角色对象失败:" + cause.getMessage());
            }
            @Override
            public R<List<SysUser>> queryUserByPhoneList(List<String> phoneList) {
                return R.fail("通过手机号集合查询用户失败:" + cause.getMessage());
            }
            @Override
            public R<Boolean> addUserRole(List<SysUserRoleDTO> dtoList) {
                return R.fail("默认批量添加修理厂失败:" + cause.getMessage());
            }
            @Override
            public R<SysUser> queryUserByPhone(String phone) {
                return R.fail("通过手机号查询用户失败:" + cause.getMessage());
            }
            @Override
            public R<SysUser> queryUserByUserName(String userName) {
                return R.fail("通过账号查询用户失败:" + cause.getMessage());
            }
        };
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/feignClient/SysUserClient.java
New file
@@ -0,0 +1,80 @@
package com.xinquan.system.api.feignClient;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.factory.SysUserFallbackFactory;
import com.xinquan.system.api.model.SysUserRoleDTO;
import java.util.List;
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;
@FeignClient(contextId = "sysUserClient", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = SysUserFallbackFactory.class)
public interface SysUserClient {
    @PostMapping("/user/getSysUser")
    R<SysUser> getSysUser(Long userId);
    @PostMapping("/user/updateSysUser")
    R<Boolean>  updateSysUser(@RequestBody SysUser sysUser);
    @PostMapping("/user/getUserList")
    R<List<SysUser>> getUserList(@RequestBody List<Integer> userIds);
    @PostMapping("/user/updateUser")
    R<Boolean>  updateUser(@RequestBody SysUser sysUser);
    /**
     * 通过用户id查询角色对象
     * @param userId
     * @return
     */
    @GetMapping("/user/queryRoleByUserId/{userId}")
    R<SysRole>  queryRoleByUserId(@PathVariable("userId") Long userId);
    /**
     * 通过角色id查询角色对象
     * @param roleId
     * @return
     */
    @GetMapping("/user/queryRoleByRoleId/{roleId}")
    R<SysRole>  queryRoleByRoleId(@PathVariable("roleId") Long roleId);
    /**
     * 通过手机号集合查询用户
     * @param phoneList
     * @return
     */
    @PostMapping("/user/queryUserByPhoneList")
    R<List<SysUser>>  queryUserByPhoneList(@RequestBody List<String> phoneList);
    /**
     * 默认批量添加修理厂
     * @param dtoList
     * @return
     */
    @PostMapping("/user/addUserRole")
    R<Boolean>  addUserRole(@RequestBody List<SysUserRoleDTO> dtoList);
    /**
     * 通过手机号查询用户
     * @param phone
     * @return
     */
    @PostMapping("/user/queryUserByPhone")
    R<SysUser>  queryUserByPhone(@RequestBody String phone);
    /**
     * 通过账号查询用户
     * @param userName
     * @return
     */
    @PostMapping("/user/queryUserByUserName")
    R<SysUser>  queryUserByUserName(@RequestBody String userName);
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyAddSysUserDto.java
New file
@@ -0,0 +1,13 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
@Data
public class CompanyAddSysUserDto {
    List<CompanyUserListVo> list;
    @ApiModelProperty("公司id")
    private Integer companyId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanySysUserReq.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.system.api.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CompanySysUserReq {
    private Integer companyId;
    private String name;
    private List<Integer> userIds;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/CompanyUserListVo.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.system.api.model;
import lombok.Data;
@Data
public class CompanyUserListVo {
    private Long id;
    private String userName;
    private String phoneNumber;
    private String password;
    private String nickName;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/LoginUser.java
New file
@@ -0,0 +1,150 @@
package com.xinquan.system.api.model;
import java.io.Serializable;
import java.util.Set;
import com.xinquan.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<String> permissions;
    /**
     * 角色列表
     */
    private Set<String> 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<String> getPermissions()
    {
        return permissions;
    }
    public void setPermissions(Set<String> permissions)
    {
        this.permissions = permissions;
    }
    public Set<String> getRoles()
    {
        return roles;
    }
    public void setRoles(Set<String> roles)
    {
        this.roles = roles;
    }
    public SysUser getSysUser()
    {
        return sysUser;
    }
    public void setSysUser(SysUser sysUser)
    {
        this.sysUser = sysUser;
    }
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/SysUserRoleDTO.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.io.Serializable;
@Data
@ApiModel(value = "自动关联修理厂角色DTO")
public class SysUserRoleDTO implements Serializable {
    @ApiModelProperty(value = "用户id")
    private Long userId;
    @ApiModelProperty(value = "角色id")
    private Long roleId;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAdd.java
New file
@@ -0,0 +1,17 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@Data
public class TRepairShopAdd {
    @ApiModelProperty("账号")
    @NotBlank(message = "账号不能为空")
    private String phonenumber;
    @ApiModelProperty("密码")
    @NotBlank(message = "密码不能为空")
    private String pwd;
}
xinquan-api/xinquan-api-system/src/main/java/com/xinquan/system/api/model/TRepairShopAddDto.java
New file
@@ -0,0 +1,14 @@
package com.xinquan.system.api.model;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Data
public class TRepairShopAddDto {
    private List<TRepairShopAdd> list;
    @ApiModelProperty("修理场id")
    @NotNull(message = "修理厂id不能为空")
    private Integer repairId;
}
xinquan-api/xinquan-api-system/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
New file
@@ -0,0 +1,4 @@
com.xinquan.system.api.factory.RemoteUserFallbackFactory
com.xinquan.system.api.factory.RemoteLogFallbackFactory
com.xinquan.system.api.factory.RemoteFileFallbackFactory
com.xinquan.system.api.factory.SysUserFallbackFactory
xinquan-api/xinquan-api-user/pom.xml
New file
@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>com.xinquan</groupId>
    <artifactId>xinquan-api</artifactId>
    <version>3.6.2</version>
  </parent>
  <artifactId>xinquan-api-user</artifactId>
  <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
  <dependencies> <!-- RuoYi Common Core-->
    <dependency>
      <groupId>com.xinquan</groupId>
      <artifactId>xinquan-common-core</artifactId>
      <exclusions>
        <exclusion>
          <groupId>com.github.pagehelper</groupId>
          <artifactId>pagehelper-spring-boot-starter</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
  </dependencies>
</project>
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/AppUser.java
New file
@@ -0,0 +1,148 @@
package com.xinquan.user.api.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.xinquan.common.core.web.domain.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * <p>
 * 用户信息表
 * </p>
 *
 * @author mitao
 * @since 2024-08-21
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("t_app_user")
@ApiModel(value="AppUser对象", description="用户信息表")
public class AppUser extends BaseModel {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "App用户id")
    @TableId(value = "id",type = IdType.ASSIGN_ID)
    private Long id;
    @ApiModelProperty(value = "系统用户id")
    @TableField("user_id")
    private Long userId;
    @ApiModelProperty(value = "手机号码")
    @TableField("cell_phone")
    private String cellPhone;
    @ApiModelProperty(value = "苹果授权登录唯一标识")
    @TableField("apple_id")
    private String appleId;
    @ApiModelProperty(value = "微信openId")
    @TableField("wx_open_id")
    private String wxOpenId;
    @ApiModelProperty(value = "头像")
    @TableField("avatar")
    private String avatar;
    @ApiModelProperty(value = "昵称")
    @TableField("nickname")
    private String nickname;
    @ApiModelProperty(value = "签名")
    @TableField("signature")
    private String signature;
    @ApiModelProperty(value = "性别 1=男 2=女 3=保密")
    @TableField("gender")
    private Integer gender;
    @ApiModelProperty(value = "生日")
    @TableField("birthday")
    private String birthday;
    @ApiModelProperty(value = "学历")
    @TableField("education")
    private String education;
    @ApiModelProperty(value = "行业")
    @TableField("industry")
    private String industry;
    @ApiModelProperty(value = "公司")
    @TableField("company")
    private String company;
    @ApiModelProperty(value = "职业")
    @TableField("occupation")
    private String occupation;
    @ApiModelProperty(value = "所在地")
    @TableField("location")
    private String location;
    @ApiModelProperty(value = "故乡")
    @TableField("hometown")
    private String hometown;
    @ApiModelProperty(value = "邮箱")
    @TableField("email")
    private String email;
    @ApiModelProperty(value = "会员到期时间")
    @TableField("vip_expire_time")
    private LocalDateTime vipExpireTime;
    @ApiModelProperty(value = "用户状态 1=正常 2=冻结 3=注销")
    @TableField("user_status")
    private Integer userStatus;
    @ApiModelProperty(value = "冻结原因")
    @TableField("freezing_reason")
    private String freezingReason;
    @ApiModelProperty(value = "冻结操作人")
    @TableField("freezing_operator")
    private String freezingOperator;
    @ApiModelProperty(value = "梵文权限 1=是 2否")
    @TableField("sanskrit_flag")
    private Integer sanskritFlag;
    @ApiModelProperty(value = "邀请人id")
    @TableField("invite_user_id")
    private Long inviteUserId;
    @ApiModelProperty(value = "余额")
    @TableField("balance")
    private BigDecimal balance;
    @ApiModelProperty(value = "收益")
    @TableField("income")
    private BigDecimal income;
    @ApiModelProperty(value = "当前累计能量值")
    @TableField("total_energy_value")
    private Integer totalEnergyValue;
    @ApiModelProperty(value = "注册时间")
    @TableField("register_time")
    private LocalDateTime registerTime;
    @ApiModelProperty(value = "注销时间")
    @TableField("logout_time")
    private LocalDateTime logoutTime;
    @ApiModelProperty(value = "用户等级id")
    @TableField("level_setting_id")
    private Integer levelSettingId;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/domain/dto/AppUserDTO.java
New file
@@ -0,0 +1,106 @@
package com.xinquan.user.api.domain.dto;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import lombok.Builder;
import lombok.Data;
/**
 * @author mitao
 * @date 2024/8/21
 */
@Data
@Builder
public class AppUserDTO implements Serializable {
    private static final long serialVersionUID = -3850851853092651572L;
    @ApiModelProperty(value = "App用户id")
    private Long id;
    @ApiModelProperty(value = "系统用户id")
    private Long userId;
    @ApiModelProperty(value = "手机号码")
    private String cellPhone;
    @ApiModelProperty(value = "苹果授权登录唯一标识")
    private String appleId;
    @ApiModelProperty(value = "微信openId")
    private String wxOpenId;
    @ApiModelProperty(value = "头像")
    private String avatar;
    @ApiModelProperty(value = "昵称")
    private String nickname;
    @ApiModelProperty(value = "签名")
    private String signature;
    @ApiModelProperty(value = "性别 1=男 2=女 3=保密")
    private Integer gender;
    @ApiModelProperty(value = "生日")
    private String birthday;
    @ApiModelProperty(value = "学历")
    private String education;
    @ApiModelProperty(value = "行业")
    private String industry;
    @ApiModelProperty(value = "公司")
    private String company;
    @ApiModelProperty(value = "职业")
    private String occupation;
    @ApiModelProperty(value = "所在地")
    private String location;
    @ApiModelProperty(value = "故乡")
    private String hometown;
    @ApiModelProperty(value = "邮箱")
    private String email;
    @ApiModelProperty(value = "会员到期时间")
    private LocalDateTime vipExpireTime;
    @ApiModelProperty(value = "用户状态 1=正常 2=冻结 3=注销")
    private Integer userStatus;
    @ApiModelProperty(value = "冻结原因")
    private String freezingReason;
    @ApiModelProperty(value = "冻结操作人")
    private String freezingOperator;
    @ApiModelProperty(value = "梵文权限 1=是 2否")
    private Integer sanskritFlag;
    @ApiModelProperty(value = "邀请人id")
    private Long inviteUserId;
    @ApiModelProperty(value = "余额")
    private BigDecimal balance;
    @ApiModelProperty(value = "收益")
    private BigDecimal income;
    @ApiModelProperty(value = "当前累计能量值")
    private Integer totalEnergyValue;
    @ApiModelProperty(value = "注册时间")
    private LocalDateTime registerTime;
    @ApiModelProperty(value = "注销时间")
    private LocalDateTime logoutTime;
    @ApiModelProperty(value = "用户等级id")
    private Integer levelSettingId;
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/factory/RemoteAppUserFallbackFactory.java
New file
@@ -0,0 +1,33 @@
package com.xinquan.user.api.factory;
import com.xinquan.common.core.domain.R;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
 * @author mitao
 * @date 2024/8/21
 */
@Component
public class RemoteAppUserFallbackFactory implements FallbackFactory<RemoteAppUserService> {
    private static final Logger log = LoggerFactory.getLogger(RemoteAppUserFallbackFactory.class);
    @Override
    public RemoteAppUserService create(Throwable cause) {
        return new RemoteAppUserService() {
            @Override
            public R<AppUser> getUserByCondition(AppUserDTO dto, String source) {
                return R.fail("获取用户信息失败。");
            }
            @Override
            public R<Boolean> registerAppUser(AppUserDTO appUserDTO, String source) {
                return R.fail("APP用户注册失败。");
            }
        };
    }
}
xinquan-api/xinquan-api-user/src/main/java/com/xinquan/user/api/feign/RemoteAppUserService.java
New file
@@ -0,0 +1,42 @@
package com.xinquan.user.api.feign;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.ServiceNameConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.factory.RemoteAppUserFallbackFactory;
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;
/**
 * @author mitao
 * @date 2024/8/21
 */
@FeignClient(contextId = "remoteAppUserService", value = ServiceNameConstants.APP_USER, fallbackFactory = RemoteAppUserFallbackFactory.class)
public interface RemoteAppUserService {
    /**
     * 获取用户信息
     *
     * @param dto
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/getUserByCondition")
    R<AppUser> getUserByCondition(@RequestBody AppUserDTO dto,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
    /**
     * app用户注册
     *
     * @param appUserDTO
     * @param source
     * @return
     */
    @PostMapping("/inner/app-user/registerAppUser")
    R<Boolean> registerAppUser(@RequestBody AppUserDTO appUserDTO,
            @RequestHeader(SecurityConstants.FROM_SOURCE) String source);
}
xinquan-api/xinquan-api-user/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
New file
@@ -0,0 +1 @@
com.xinquan.user.api.factory.RemoteAppUserFallbackFactory
xinquan-auth/pom.xml
New file
@@ -0,0 +1,109 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xinquan</groupId>
        <artifactId>xinquan</artifactId>
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>xinquan-auth</artifactId>
    <description>
        xinquan-auth认证授权中心
    </description>
    <properties>
        <druid.version>1.1.13</druid.version>
    </properties>
    <dependencies>
        <!--user feign模块-->
        <dependency>
            <groupId>com.xinquan</groupId>
            <artifactId>xinquan-api-user</artifactId>
            <version>3.6.2</version>
        </dependency>
        <!-- SpringCloud Alibaba Nacos -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Nacos Config -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        </dependency>
        <!-- SpringCloud Alibaba Sentinel -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
        </dependency>
        <!-- SpringBoot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- SpringBoot Actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- RuoYi Common Security-->
        <dependency>
            <groupId>com.xinquan</groupId>
            <artifactId>xinquan-common-security</artifactId>
        </dependency>
        <!-- 引入Druid依赖,阿里巴巴所提供的数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <!-- RuoYi Common Swagger -->
        <dependency>
            <groupId>com.xinquan</groupId>
            <artifactId>xinquan-common-swagger</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>
xinquan-auth/src/main/java/com/xinquan/auth/XinQuanAuthApplication.java
New file
@@ -0,0 +1,37 @@
package com.xinquan.auth;
import com.xinquan.common.security.annotation.EnableRyFeignClients;
import com.xinquan.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
/**
 * 认证授权中心
 *
 * @author ruoyi
 */
@EnableCustomSwagger2
@EnableRyFeignClients
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
public class XinQuanAuthApplication
{
    public static void main(String[] args)
    {
        try {
            SpringApplication.run(XinQuanAuthApplication.class, args);
        }catch (Exception e){
            e.printStackTrace();
        }
        System.out.println("(♥◠‿◠)ノ゙  认证授权中心启动成功   ლ(´ڡ`ლ)゙  \n" +
                " .-------.       ____     __        \n" +
                " |  _ _   \\      \\   \\   /  /    \n" +
                " | ( ' )  |       \\  _. /  '       \n" +
                " |(_ o _) /        _( )_ .'         \n" +
                " | (_,_).' __  ___(_ o _)'          \n" +
                " |  |\\ \\  |  ||   |(_,_)'         \n" +
                " |  | \\ `'   /|   `-'  /           \n" +
                " |  |  \\    /  \\      /           \n" +
                " ''-'   `'-'    `-..-'              ");
    }
}
xinquan-auth/src/main/java/com/xinquan/auth/controller/TokenController.java
New file
@@ -0,0 +1,137 @@
package com.xinquan.auth.controller;
import com.xinquan.auth.form.AppRegisterBody;
import com.xinquan.auth.form.LoginBody;
import com.xinquan.auth.form.RegisterBody;
import com.xinquan.auth.service.SysLoginService;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.utils.JwtUtils;
import com.xinquan.common.core.utils.StringUtils;
import com.xinquan.common.security.auth.AuthUtil;
import com.xinquan.common.security.service.TokenService;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.domain.SysRole;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.feignClient.SysUserClient;
import com.xinquan.system.api.model.LoginUser;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * token 控制
 *
 * @author ruoyi
 */
@RestController
public class TokenController
{
    @Autowired
    private TokenService tokenService;
    @Autowired
    private SysLoginService sysLoginService;
    @Autowired
    private SysUserClient userClient;
    /**
     * 发送验证码
     * @param cellPhone 手机号码
     * @return
     */
    @GetMapping("/app/send-captcha-code")
    @ApiOperation(value = "发送验证码",tags = {"APP端"})
    @ApiImplicitParams({@ApiImplicitParam(name = "cellPhone",value = "手机号码",required = true,dataType = "String",paramType = "query")})
    public R<?> sendCaptchaCode(@RequestParam("cellPhone") String cellPhone) {
        sysLoginService.sendCaptchaCode(cellPhone);
        return R.ok();
    }
    /**
     * app注册账户
     * @param appRegisterBody APP端注册对象
     * @return msg
     */
    @ApiOperation(value = "注册账户",tags = {"APP端"})
    @PostMapping("/app/register")
    public R<?> appRegister(@RequestBody AppRegisterBody appRegisterBody)
    {
        // 用户注册
        sysLoginService.appRegister(appRegisterBody);
        return R.ok();
    }
    @ApiOperation(value = "管理后台登录",tags = {"管理后台"})
    @PostMapping("login")
    public R<?> login(@RequestBody LoginBody form)
    {
        // 用户登录
        LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword());
        HashMap<String, Object> map = new HashMap<>();
        map.put("token",tokenService.createToken(userInfo));
        List<SysRole> roles = userInfo.getSysUser().getRoles();
        if(CollectionUtils.isEmpty(roles)){
            return R.fail("请关联角色!");
        }
        map.put("roleName",roles.get(0).getRoleName());
        map.put("info",userInfo);
        // 修改用户最后登录时间
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userInfo.getSysUser().getUserId());
        sysUser.setLoginDate(new Date());
        System.out.println("修改用户登录时间"+sysUser);
        userClient.updateSysUser(sysUser);
        // 获取登录token
        return R.ok(map);
    }
    @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();
    }
}
xinquan-auth/src/main/java/com/xinquan/auth/form/AppRegisterBody.java
New file
@@ -0,0 +1,36 @@
package com.xinquan.auth.form;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable;
import javax.validation.constraints.NotBlank;
import lombok.Data;
/**
 * 用户注册对象
 *
 * @author ruoyi
 */
@Data
@ApiModel(value = "APP端注册对象", description = "APP端注册对象")
public class AppRegisterBody implements Serializable
{
    private static final long serialVersionUID = 438348119520198682L;
    @ApiModelProperty(value = "电话号码")
    @NotBlank(message = "电话号码不能为空")
    private String cellPhone;
    @ApiModelProperty(value = "用户密码")
    @NotBlank(message = "用户密码不能为空")
    private String password;
    @ApiModelProperty("验证码")
    @NotBlank(message = "验证码不能为空")
    private String verifyCode;
    @ApiModelProperty("邀请人id")
    private Long inviteUserId;
}
xinquan-auth/src/main/java/com/xinquan/auth/form/LoginBody.java
New file
@@ -0,0 +1,28 @@
package com.xinquan.auth.form;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
/**
 * 用户登录对象
 *
 * @author ruoyi
 */
@Setter
@Getter
public class LoginBody
{
    /**
     * 用户名
     */
    @ApiModelProperty(value = "用户名")
    private String username;
    /**
     * 用户密码
     */
    @ApiModelProperty(value = "用户密码")
    private String password;
}
xinquan-auth/src/main/java/com/xinquan/auth/form/RegisterBody.java
New file
@@ -0,0 +1,13 @@
package com.xinquan.auth.form;
/**
 * 用户注册对象
 *
 * @author ruoyi
 */
public class RegisterBody extends LoginBody
{
}
xinquan-auth/src/main/java/com/xinquan/auth/service/SysLoginService.java
New file
@@ -0,0 +1,251 @@
package com.xinquan.auth.service;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.xinquan.auth.form.AppRegisterBody;
import com.xinquan.common.core.constant.CacheConstants;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.UserConstants;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.enums.UserStatus;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.core.text.Convert;
import com.xinquan.common.core.utils.StringUtils;
import com.xinquan.common.core.utils.ip.IpUtils;
import com.xinquan.common.redis.service.RedisService;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.system.api.RemoteUserService;
import com.xinquan.system.api.domain.SysUser;
import com.xinquan.system.api.model.LoginUser;
import com.xinquan.user.api.domain.AppUser;
import com.xinquan.user.api.domain.dto.AppUserDTO;
import com.xinquan.user.api.feign.RemoteAppUserService;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
 * 登录校验方法
 *
 * @author ruoyi
 */
@Slf4j
@Component
public class SysLoginService
{
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private SysPasswordService passwordService;
    @Autowired
    private SysRecordLogService recordLogService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private RemoteAppUserService remoteAppUserService;
    /**
     * 登录
     */
    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<LoginUser> 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, "注册成功");
    }
    /**
     * 注册
     */
    public void appRegister(AppRegisterBody appRegisterBody)
    {
        String cellPhone = appRegisterBody.getCellPhone();
        String password = appRegisterBody.getPassword();
        //验证码校验
        if (!verifyCode(cellPhone, appRegisterBody.getVerifyCode()))
        {
            throw new ServiceException("验证码错误");
        }
        //调用远程服务查询用户信息
        AppUser appUser = remoteAppUserService.getUserByCondition(
                AppUserDTO.builder().cellPhone(cellPhone).build(),
                SecurityConstants.INNER).getData();
        if (Objects.nonNull(appUser))
        {
            throw new ServiceException("该手机号已注册");
        }
        if (password.length() < UserConstants.PASSWORD_MIN_LENGTH
                || password.length() > UserConstants.PASSWORD_MAX_LENGTH)
        {
            throw new ServiceException("密码长度必须在5到20个字符之间");
        }
        String nickname = "用户" + IdUtil.fastSimpleUUID().substring(0, 6);
        // 注册用户信息
        SysUser sysUser = new SysUser();
        sysUser.setUserName(cellPhone);
        sysUser.setNickName(nickname);
        sysUser.setPassword(SecurityUtils.encryptPassword(password));
        R<SysUser> registerResult = remoteUserService.registerAppUserInfo(sysUser, SecurityConstants.INNER);
        if (R.FAIL == registerResult.getCode())
        {
            throw new ServiceException(registerResult.getMsg());
        }
        recordLogService.recordLogininfor(cellPhone, Constants.REGISTER, "注册成功");
        //TODO 默认头像待完善
        AppUserDTO appUserDTO = AppUserDTO.builder().userId(sysUser.getUserId()).cellPhone(cellPhone)
                .avatar("qwer").nickname(
                        nickname).userStatus(1).sanskritFlag(2).balance(BigDecimal.ZERO)
                .income(BigDecimal.ZERO).totalEnergyValue(0).registerTime(
                        LocalDateTime.now()).levelSettingId(1).build();
        Boolean result = remoteAppUserService.registerAppUser(appUserDTO, SecurityConstants.INNER)
                .getData();
        if (!result) {
            throw new ServiceException("注册失败");
        }
    }
    /**
     * 校验验证码
     * @param cellPhone 手机号
     * @param verifyCode 验证码
     * @return true/false
     */
    private boolean verifyCode(String cellPhone, String verifyCode) {
        if (StringUtils.isNotBlank(cellPhone) && StringUtils.isNotBlank(verifyCode)) {
            String key = CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone;
            String code = redisService.getCacheObject(key);
            if (StringUtils.isNotBlank(code) && code.equals(verifyCode)) {
                redisService.deleteObject(key);
                return true;
            }
        }
        return false;
    }
    /**
     * 发送验证码
     * @param cellPhone 手机号码
     */
    public void sendCaptchaCode(String cellPhone) {
        Boolean result = redisService.hasKey(
                CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone);
        if (result) {
            throw new ServiceException("请勿重复发送验证码");
        }
        String code = RandomUtil.randomNumbers(6);
        try {
            //TODO 发送短信
            log.info("发送验证码成功,手机号:{} 验证码:{}", cellPhone,code);
        } catch (Exception e) {
            log.error("发送短信失败", e);
            throw new ServiceException("验证码发送失败");
        }
        //将验证码放入redis
        redisService.setCacheObject(CacheConstants.APP_CAPTCHA_CODE_PREFIX + cellPhone, code, 5L,
                TimeUnit.MINUTES);
    }
}
xinquan-auth/src/main/java/com/xinquan/auth/service/SysPasswordService.java
New file
@@ -0,0 +1,85 @@
package com.xinquan.auth.service;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xinquan.common.core.constant.CacheConstants;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.exception.ServiceException;
import com.xinquan.common.redis.service.RedisService;
import com.xinquan.common.security.utils.SecurityUtils;
import com.xinquan.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));
        }
    }
}
xinquan-auth/src/main/java/com/xinquan/auth/service/SysRecordLogService.java
New file
@@ -0,0 +1,48 @@
package com.xinquan.auth.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.utils.StringUtils;
import com.xinquan.common.core.utils.ip.IpUtils;
import com.xinquan.system.api.RemoteLogService;
import com.xinquan.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);
    }
}
xinquan-auth/src/main/resources/banner.txt
New file
@@ -0,0 +1,10 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}
                            _                        _    _
                           (_)                      | |  | |
 _ __  _   _   ___   _   _  _  ______   __ _  _   _ | |_ | |__
| '__|| | | | / _ \ | | | || ||______| / _` || | | || __|| '_ \
| |   | |_| || (_) || |_| || |        | (_| || |_| || |_ | | | |
|_|    \__,_| \___/  \__, ||_|         \__,_| \__,_| \__||_| |_|
                      __/ |
                     |___/
xinquan-auth/src/main/resources/logback.xml
New file
@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!-- 日志存放路径 -->
    <property name="log.path" value="logs/xinquan-auth" />
   <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>INFO</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!-- 系统模块日志级别控制  -->
    <logger name="com.xinquan" level="info" />
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn" />
    <root level="info">
        <appender-ref ref="console" />
    </root>
    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>
</configuration>
xinquan-common/pom.xml
New file
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xinquan</groupId>
        <artifactId>xinquan</artifactId>
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <modules>
        <module>xinquan-common-log</module>
        <module>xinquan-common-core</module>
        <module>xinquan-common-redis</module>
        <module>xinquan-common-seata</module>
        <module>xinquan-common-swagger</module>
        <module>xinquan-common-security</module>
        <module>xinquan-common-datascope</module>
        <module>xinquan-common-datasource</module>
    </modules>
    <artifactId>xinquan-common</artifactId>
    <packaging>pom</packaging>
    <description>
        xinquan-common通用模块
    </description>
    <dependencies>
        <!--lombok-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--hutool工具包-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
    </dependencies>
</project>
xinquan-common/xinquan-common-core/pom.xml
New file
@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://maven.apache.org/POM/4.0.0"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>com.xinquan</groupId>
        <artifactId>xinquan-common</artifactId>
        <version>3.6.2</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>xinquan-common-core</artifactId>
    <description>
        xinquan-common-core核心模块
    </description>
    <dependencies>
        <!-- SpringCloud Openfeign -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- SpringCloud Loadbalancer -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- Spring Context Support -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <!-- Spring Web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <!-- Transmittable ThreadLocal -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>transmittable-thread-local</artifactId>
        </dependency>
        <!-- Pagehelper -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
        <!-- Hibernate Validator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!-- Jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <!-- Alibaba Fastjson -->
        <dependency>
            <groupId>com.alibaba.fastjson2</groupId>
            <artifactId>fastjson2</artifactId>
        </dependency>
        <!-- Jwt -->
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>
        <!-- Jaxb -->
        <dependency>
            <groupId>javax.xml.bind</groupId>
            <artifactId>jaxb-api</artifactId>
        </dependency>
        <!-- Apache Lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <!-- Commons Io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
        </dependency>
        <!-- excel工具 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
        </dependency>
        <!-- Java Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
        </dependency>
        <!-- Swagger -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.2</version>
        </dependency>
        <!--华为云的obs-->
        <dependency>
            <groupId>com.huaweicloud</groupId>
            <artifactId>esdk-obs-java</artifactId>
            <version>3.19.5</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.9.3</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okio</groupId>
            <artifactId>okio</artifactId>
            <version>2.8.0</version>
        </dependency>
    </dependencies>
</project>
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/annotation/Excel.java
New file
@@ -0,0 +1,182 @@
package com.xinquan.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.xinquan.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;
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/annotation/Excels.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.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();
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/CacheConstants.java
New file
@@ -0,0 +1,60 @@
package com.xinquan.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";
    public static final String APP_CAPTCHA_CODE_PREFIX = "app_captcha_code:";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/Constants.java
New file
@@ -0,0 +1,136 @@
package com.xinquan.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.xinquan" };
    /**
     * 时间格式化
     */
    public static final String DATE_FORMATTER_TIME = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMATTER_DATE = "yyyy-MM-dd";
    /**
     * 定时任务违规的字符
     */
    public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
            "org.springframework", "org.apache", "com.xinquan.common.core.utils.file" };
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/GenConstants.java
New file
@@ -0,0 +1,117 @@
package com.xinquan.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", "del_flag" };
    /** 页面不需要显示的列表字段 */
    public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time" };
    /** 页面不需要查询字段 */
    public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
            "update_time", "remark" };
    /** Entity基类字段 */
    public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
    /** 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";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/HttpStatus.java
New file
@@ -0,0 +1,94 @@
package com.xinquan.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;
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ScheduleConstants.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.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;
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/SecurityConstants.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.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";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/ServiceNameConstants.java
New file
@@ -0,0 +1,38 @@
package com.xinquan.common.core.constant;
/**
 * 服务名称
 *
 * @author ruoyi
 */
public class ServiceNameConstants
{
    /**
     * 认证服务的serviceid
     */
    public static final String AUTH_SERVICE = "xinquan-auth";
    /**
     * 系统模块的serviceid
     */
    public static final String SYSTEM_SERVICE = "xinquan-system";
    /**
     * 文件服务的serviceid
     */
    public static final String FILE_SERVICE = "xinquan-file";
    /**
     * 课程服务的serviceid
     */
    public static final String COURSE = "xinquan-course";
    /**
     * 车辆服务的serviceid
     */
    public static final String APP_USER = "xinquan-user";
    /**
     * 车辆合同的serviceid
     */
    public static final String CONTRACT_SERVICE = "xinquan-contract";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/TokenConstants.java
New file
@@ -0,0 +1,25 @@
package com.xinquan.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";
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/constant/UserConstants.java
New file
@@ -0,0 +1,80 @@
package com.xinquan.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;
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/context/SecurityContextHolder.java
New file
@@ -0,0 +1,98 @@
package com.xinquan.common.core.context;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.alibaba.ttl.TransmittableThreadLocal;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.text.Convert;
import com.xinquan.common.core.utils.StringUtils;
/**
 * 获取当前线程变量中的 用户id、用户名称、Token等信息
 * 注意: 必须在网关通过请求头的方法传入,同时在HeaderInterceptor拦截器设置值。 否则这里无法获取
 *
 * @author ruoyi
 */
public class SecurityContextHolder
{
    private static final TransmittableThreadLocal<Map<String, Object>> THREAD_LOCAL = new TransmittableThreadLocal<>();
    public static void set(String key, Object value)
    {
        Map<String, Object> map = getLocalMap();
        map.put(key, value == null ? StringUtils.EMPTY : value);
    }
    public static String get(String key)
    {
        Map<String, Object> map = getLocalMap();
        return Convert.toStr(map.getOrDefault(key, StringUtils.EMPTY));
    }
    public static <T> T get(String key, Class<T> clazz)
    {
        Map<String, Object> map = getLocalMap();
        return StringUtils.cast(map.getOrDefault(key, null));
    }
    public static Map<String, Object> getLocalMap()
    {
        Map<String, Object> map = THREAD_LOCAL.get();
        if (map == null)
        {
            map = new ConcurrentHashMap<String, Object>();
            THREAD_LOCAL.set(map);
        }
        return map;
    }
    public static void setLocalMap(Map<String, Object> 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();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/domain/R.java
New file
@@ -0,0 +1,115 @@
package com.xinquan.common.core.domain;
import java.io.Serializable;
import com.xinquan.common.core.constant.Constants;
/**
 * 响应信息主体
 *
 * @author ruoyi
 */
public class R<T> 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 <T> R<T> ok()
    {
        return restResult(null, SUCCESS, null);
    }
    public static <T> R<T> ok(T data)
    {
        return restResult(data, SUCCESS, null);
    }
    public static <T> R<T> ok(T data, String msg)
    {
        return restResult(data, SUCCESS, msg);
    }
    public static <T> R<T> fail()
    {
        return restResult(null, FAIL, null);
    }
    public static <T> R<T> fail(String msg)
    {
        return restResult(null, FAIL, msg);
    }
    public static <T> R<T> fail(T data)
    {
        return restResult(data, FAIL, null);
    }
    public static <T> R<T> fail(T data, String msg)
    {
        return restResult(data, FAIL, msg);
    }
    public static <T> R<T> fail(int code, String msg)
    {
        return restResult(null, code, msg);
    }
    private static <T> R<T> restResult(T data, int code, String msg)
    {
        R<T> 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 <T> Boolean isError(R<T> ret)
    {
        return !isSuccess(ret);
    }
    public static <T> Boolean isSuccess(R<T> ret)
    {
        return R.SUCCESS == ret.getCode();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ApproveConfigEnum.java
New file
@@ -0,0 +1,47 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ApproveConfigEnum {
    /*审批类型 1=交车审批、2=续约审批、3=退车审批*/
    DELIVERY_APPROVAL(1, "交车审批"),
    RENEWAL_APPROVAL(2, "续约审批"),
    RETURN_APPROVAL(3, "退车审批");
    @Getter
    private String desc;
    @Getter
    private int code;
    ApproveConfigEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ApproveConfigEnum fromCode(Integer code) {
        ApproveConfigEnum[] resultTypes = ApproveConfigEnum.values();
        for (ApproveConfigEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditStateEnum.java
New file
@@ -0,0 +1,48 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum AuditStateEnum {
    /*审核状态 0待审批 1通过 2驳回 3已撤回*/
    PENDING_APPROVAL(0, "待审批"),
    APPROVED(1, "审批通过"),
    APPROVAL_REJECTION(2, "审批驳回"),
    WITHDRAWN(3, "已撤回");
    @Getter
    private String desc;
    @Getter
    private int code;
    AuditStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static AuditStateEnum fromCode(Integer code) {
        AuditStateEnum[] resultTypes = AuditStateEnum.values();
        for (AuditStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/AuditTypeEnum.java
New file
@@ -0,0 +1,48 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum AuditTypeEnum {
    /*审核类型 1交车申请 2续约申请 3退车申请  4事故账单申请*/
    DELIVERY_APPLICATION(1, "交车申请"),
    RENEWAL_APPLICATION(2, "续约申请"),
    RETURN_APPLICATION(3, "退车申请"),
    ACCIDENT_BILL_APPLICATION(4, "事故账单申请");
    @Getter
    private String desc;
    @Getter
    private int code;
    AuditTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static AuditTypeEnum fromCode(Integer code) {
        AuditTypeEnum[] resultTypes = AuditTypeEnum.values();
        for (AuditTypeEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarColorEnum.java
New file
@@ -0,0 +1,56 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum CarColorEnum {
    /*1=白色、2=黑色、3=银色、4=灰色、5=红色、6=蓝色、7=绿色、8=黄色、9=金色、10=紫色、11=橙色、12=其他*/
    WHITE(1, "白色"),
    BLACK(2, "黑色"),
    SILVERY(3, "银色"),
    GREY(4, "灰色"),
    RED(5, "红色"),
    BLUE(6, "蓝色"),
    GREEN(7, "绿色"),
    YELLOW(8, "黄色"),
    GOLDEN(9, "金色"),
    PURPLE(10, "紫色"),
    ORANGE(11, "橙色"),
    OTHER(12, "其他");
    @Getter
    private String desc;
    @Getter
    private int code;
    CarColorEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static CarColorEnum fromCode(Integer code) {
        CarColorEnum[] resultTypes = CarColorEnum.values();
        for (CarColorEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/CarStateEnum.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum CarStateEnum {
    /*状态1= 待上户、2=待办证、3=待整备、4=待租、5=已租、6=已处置*/
    PENDING_REGISTRATION(1, "待上户"),
    PENDING_CERTIFICATE(2, "待办证"),
    TO_BE_PREPARED(3, "待整备"),
    FOR_RENT(4, "待租"),
    RENTED(5, "已租"),
    DISPOSED(6, "已处置");
    @Getter
    private String desc;
    @Getter
    private int code;
    CarStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static CarStateEnum fromCode(Integer code) {
        CarStateEnum[] resultTypes = CarStateEnum.values();
        for (CarStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractStateEnum.java
New file
@@ -0,0 +1,55 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ContractStateEnum {
    /*合同状态 1签约中 2审批拒绝 3续约中 4待执行 5执行中 6结算中 7已结束 8已作废 9即将到期 10已到期 11已撤销*/
    SIGNING(1, "签约中"),
    APPROVAL_REJECTION(2, "审批拒绝"),
    UNDER_RENEWAL(3, "续约中"),
    TO_BE_EXECUTED(4, "待执行"),
    UNDER_EXECUTION(5, "执行中"),
    SETTLEMENT_PROGRESS(6, "结算中"),
    ENDED(7, "已结束"),
    VOIDED(8, "已作废"),
    DUE(9, "即将到期"),
    EXPIRED(10, "已到期"),
    REVOKED(11, "已撤销");
    @Getter
    private String desc;
    @Getter
    private int code;
    ContractStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ContractStateEnum fromCode(Integer code) {
        ContractStateEnum[] resultTypes = ContractStateEnum.values();
        for (ContractStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ContractTypeEnum.java
New file
@@ -0,0 +1,46 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ContractTypeEnum {
    /*合同类型 1=纯租 2=以租代购 3=打工模式*/
    PURE_RENT(1, "纯租"),
    CAR_LEASE(2, "以租代购"),
    WORKING_MODE(3, "打工模式");
    @Getter
    private String desc;
    @Getter
    private int code;
    ContractTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ContractTypeEnum fromCode(Integer code) {
        ContractTypeEnum[] resultTypes = ContractTypeEnum.values();
        for (ContractTypeEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/DisabledEnum.java
New file
@@ -0,0 +1,43 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @author xiaochen
 * @ClassName Disable
 * @Description
 * @date 2022-06-08 16:55
 */
public enum DisabledEnum {
    NO(0, "否"),
    YES(1, "是");
    @Getter
    private String desc;
    @Getter
    private int code;
    DisabledEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static DisabledEnum fromCode(Integer code) {
        DisabledEnum[] resultTypes = DisabledEnum.values();
        for (DisabledEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/HandoverStateEnum.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum HandoverStateEnum {
    /*交车状态 1待交车 2待审批 3已交车 4审批拒绝*/
    VEHICLE_DELIVERED(1, "待交车"),
    PENDING_APPROVAL(2, "待审批"),
    DELIVERED(3, "已交车"),
    APPROVAL_REJECTION(4, "审批拒绝"),
    REVOKED(5, "已撤销");
    @Getter
    private String desc;
    @Getter
    private int code;
    HandoverStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static HandoverStateEnum fromCode(Integer code) {
        HandoverStateEnum[] resultTypes = HandoverStateEnum.values();
        for (HandoverStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ImportTypeEnum.java
New file
@@ -0,0 +1,56 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ImportTypeEnum {
    /*1=新车车辆导入 、2=已有车辆导入、3=上户导入、4=设备导入、5=违章导入、6=违章图片导入、7=保养记录导入、8=保单导入、9=合同导入*/
    NEW_CAR(1, "新车车辆导入"),
    EXIST_CAR(2, "已有车辆导入"),
    WEALTHY(3, "上户导入"),
    DEVICE(4, "设备导入"),
    VIOLATION(5, "违章导入"),
    VIOLATION_PICTURE(6, "违章图片导入"),
    SERVICE(7, "保养记录导入"),
    WARRANTY(8, "保单导入"),
    CONTRACT(9, "合同导入"),
    CERTIFICATE(10, "办证导入"),
    INSPECTANNUALLY(11, "车辆年检导入"),
    MAINTENANCE(12, "车辆维修导入");
    @Getter
    private String desc;
    @Getter
    private int code;
    ImportTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ImportTypeEnum fromCode(Integer code) {
        ImportTypeEnum[] resultTypes = ImportTypeEnum.values();
        for (ImportTypeEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/InsureTypeEnum.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum InsureTypeEnum {
    /*保险类型 1=商业险、2=交强险、3=承运人责任险、4=客伤险、5=盗抢险*/
    COMMERCIAL_INSURANCE(1, "商业险"),
    COMPULSORY_INSURANCE(2, "交强险"),
    CARRIER_LIABILITY_INSURANCE(3, "承运人责任险"),
    CUSTOMER_INJURY_INSURANCE(4, "客伤险"),
    THEFT_INSURANCE(5, "盗抢险");
    @Getter
    private String desc;
    @Getter
    private int code;
    InsureTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static InsureTypeEnum fromCode(Integer code) {
        InsureTypeEnum[] resultTypes = InsureTypeEnum.values();
        for (InsureTypeEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/PurchaseStateEnum.java
New file
@@ -0,0 +1,48 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum PurchaseStateEnum {
    /*购买状态 1在保 2停保 3复保 4脱保*/
    UNDER_PROTECTION(1, "在保"),
    SUSPENSION_MAINTENANCE(2, "停保"),
    REINSURANCE(3, "复保"),
    DELISTING(4, "脱保");
    @Getter
    private String desc;
    @Getter
    private int code;
    PurchaseStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static PurchaseStateEnum fromCode(Integer code) {
        PurchaseStateEnum[] resultTypes = PurchaseStateEnum.values();
        for (PurchaseStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnCarTypeEnum.java
New file
@@ -0,0 +1,46 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ReturnCarTypeEnum {
    /*合同类型 合同到期、提前退车、强制收车*/
    EXPIRE(1, "合同到期"),
    EARLY_WITHDRAWAL(2, "提前退车"),
    COMPULSORY_COLLECTION(3, "强制收车");
    @Getter
    private String desc;
    @Getter
    private int code;
    ReturnCarTypeEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ReturnCarTypeEnum fromCode(Integer code) {
        ReturnCarTypeEnum[] resultTypes = ReturnCarTypeEnum.values();
        for (ReturnCarTypeEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/ReturnStateEnum.java
New file
@@ -0,0 +1,50 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum ReturnStateEnum {
    /*退车状态 1=待验车 2=待生成账单 3=待审批 4=已退车 5=审批拒绝*/
    VEHICLE_INSPECTED(1, "待验车"),
    PENDING_BILL_GENERATION(2, "待生成账单"),
    PENDING_APPROVAL(3, "待审批"),
    RETURNED_VEHICLE(4, "已退车"),
    APPROVAL_REJECTION(5, "审批拒绝"),
    REVOKED(6, "已撤销");
    @Getter
    private String desc;
    @Getter
    private int code;
    ReturnStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static ReturnStateEnum fromCode(Integer code) {
        ReturnStateEnum[] resultTypes = ReturnStateEnum.values();
        for (ReturnStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/UserStatus.java
New file
@@ -0,0 +1,30 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/enums/WarrantyStateEnum.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.common.core.enums;
import lombok.Getter;
/**
 * @Description
 * @Author xiaochen
 * @Date 2023/6/8 16:42
 */
public enum WarrantyStateEnum {
    /*保单状态 1正常 2已脱保 3已停保 4即将到期 5建议停保*/
    NORMAL(1, "正常"),
    DELISTED(2, "已脱保"),
    DISCONTINUED_WARRANTY(3, "已停保"),
    DUE(4, "即将到期"),
    SUGGEST_DISCONTINUING_MAINTENANCE(5, "建议停保");
    @Getter
    private String desc;
    @Getter
    private int code;
    WarrantyStateEnum(int code, String desc) {
        this.code = code;
        this.desc = desc;
    }
    /**
     * 通过code获取枚举
     *
     * @param code
     * @return
     */
    public static WarrantyStateEnum fromCode(Integer code) {
        WarrantyStateEnum[] resultTypes = WarrantyStateEnum.values();
        for (WarrantyStateEnum resultType : resultTypes) {
            if (code.equals(resultType.getCode())) {
                return resultType;
            }
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/CaptchaException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.common.core.exception;
/**
 * 验证码错误异常类
 *
 * @author ruoyi
 */
public class CaptchaException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public CaptchaException(String msg)
    {
        super(msg);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/CheckedException.java
New file
@@ -0,0 +1,31 @@
package com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/DemoModeException.java
New file
@@ -0,0 +1,15 @@
package com.xinquan.common.core.exception;
/**
 * 演示模式异常
 *
 * @author ruoyi
 */
public class DemoModeException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public DemoModeException()
    {
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/GlobalException.java
New file
@@ -0,0 +1,58 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/InnerAuthException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.common.core.exception;
/**
 * 内部认证异常
 *
 * @author ruoyi
 */
public class InnerAuthException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public InnerAuthException(String message)
    {
        super(message);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/PreAuthorizeException.java
New file
@@ -0,0 +1,15 @@
package com.xinquan.common.core.exception;
/**
 * 权限异常
 *
 * @author ruoyi
 */
public class PreAuthorizeException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public PreAuthorizeException()
    {
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/ServiceException.java
New file
@@ -0,0 +1,74 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/UtilException.java
New file
@@ -0,0 +1,26 @@
package com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotLoginException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.common.core.exception.auth;
/**
 * 未能通过的登录认证异常
 *
 * @author ruoyi
 */
public class NotLoginException extends RuntimeException
{
    private static final long serialVersionUID = 1L;
    public NotLoginException(String message)
    {
        super(message);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotPermissionException.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.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, ","));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/auth/NotRoleException.java
New file
@@ -0,0 +1,23 @@
package com.xinquan.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, ","));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/base/BaseException.java
New file
@@ -0,0 +1,79 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileException.java
New file
@@ -0,0 +1,19 @@
package com.xinquan.common.core.exception.file;
import com.xinquan.common.core.exception.base.BaseException;
/**
 * 文件信息异常类
 *
 * @author ruoyi
 */
public class FileException extends BaseException
{
    private static final long serialVersionUID = 1L;
    public FileException(String code, Object[] args, String msg)
    {
        super("file", code, args, msg);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileNameLengthLimitExceededException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.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 }, "the filename is too long");
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileSizeLimitExceededException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.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 }, "the filesize is too large");
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/FileUploadException.java
New file
@@ -0,0 +1,61 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/file/InvalidExtensionException.java
New file
@@ -0,0 +1,80 @@
package com.xinquan.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);
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/job/TaskException.java
New file
@@ -0,0 +1,34 @@
package com.xinquan.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
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/CaptchaExpireException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.common.core.exception.user;
/**
 * 验证码失效异常类
 *
 * @author ruoyi
 */
public class CaptchaExpireException extends UserException
{
    private static final long serialVersionUID = 1L;
    public CaptchaExpireException()
    {
        super("user.jcaptcha.expire", null);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/UserException.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.common.core.exception.user;
import com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/exception/user/UserPasswordNotMatchException.java
New file
@@ -0,0 +1,16 @@
package com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/query/TimeRangePageQuery.java
New file
@@ -0,0 +1,52 @@
package com.xinquan.common.core.query;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.xinquan.common.core.web.page.BasePage;
import com.xinquan.common.core.web.page.TableDataInfo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Objects;
/**
 * @author xiaochen
 * @ClassName TimeRangePageDTO
 * @Description
 * @date 2023-06-4 14:42
 */
@ApiModel("时间范围分页dto")
public class TimeRangePageQuery extends BasePage {
    @ApiModelProperty("开始时间 格式 yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date startTime;
    @ApiModelProperty("结束时间 格式 yyyy-MM-dd")
    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
    private Date endTime;
    public String getStartTime() {
        if (Objects.nonNull(startTime)) {
            return new SimpleDateFormat("yyyy-MM-dd").format(startTime) + " 00:00:00";
        }
        return null;
    }
    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }
    public String getEndTime() {
        if (Objects.nonNull(endTime)) {
            return new SimpleDateFormat("yyyy-MM-dd").format(endTime) + " 23:59:59";
        }
        return null;
    }
    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/CharsetKit.java
New file
@@ -0,0 +1,86 @@
package com.xinquan.common.core.text;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import com.xinquan.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();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/Convert.java
New file
@@ -0,0 +1,1006 @@
package com.xinquan.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.xinquan.common.core.utils.StringUtils;
/**
 * 类型转换器
 *
 * @author ruoyi
 */
public class Convert
{
    /**
     * 转换为字符串<br>
     * 如果给定的值为null,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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();
    }
    /**
     * 转换为字符串<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static String toStr(Object value)
    {
        return toStr(value, null);
    }
    /**
     * 转换为字符<br>
     * 如果给定的值为null,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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);
    }
    /**
     * 转换为字符<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Character toChar(Object value)
    {
        return toChar(value, null);
    }
    /**
     * 转换为byte<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Byte toByte(Object value)
    {
        return toByte(value, null);
    }
    /**
     * 转换为Short<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Short toShort(Object value)
    {
        return toShort(value, null);
    }
    /**
     * 转换为Number<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Number toNumber(Object value)
    {
        return toNumber(value, null);
    }
    /**
     * 转换为int<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Integer toInt(Object value)
    {
        return toInt(value, null);
    }
    /**
     * 转换为Integer数组<br>
     *
     * @param str 被转换的值
     * @return 结果
     */
    public static Integer[] toIntArray(String str)
    {
        return toIntArray(",", str);
    }
    /**
     * 转换为Long数组<br>
     *
     * @param str 被转换的值
     * @return 结果
     */
    public static Long[] toLongArray(String str)
    {
        return toLongArray(",", str);
    }
    /**
     * 转换为Integer数组<br>
     *
     * @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数组<br>
     *
     * @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数组<br>
     *
     * @param str 被转换的值
     * @return 结果
     */
    public static String[] toStrArray(String str)
    {
        return toStrArray(",", str);
    }
    /**
     * 转换为String数组<br>
     *
     * @param split 分隔符
     * @param str 被转换的值
     * @return 结果
     */
    public static String[] toStrArray(String split, String str)
    {
        return str.split(split);
    }
    /**
     * 转换为long<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为<code>null</code>,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Long toLong(Object value)
    {
        return toLong(value, null);
    }
    /**
     * 转换为double<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Double toDouble(Object value)
    {
        return toDouble(value, null);
    }
    /**
     * 转换为Float<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Float toFloat(Object value)
    {
        return toFloat(value, null);
    }
    /**
     * 转换为boolean<br>
     * String支持的值为:true、false、yes、ok、no,1,0 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static Boolean toBool(Object value)
    {
        return toBool(value, null);
    }
    /**
     * 转换为Enum对象<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     *
     * @param clazz Enum的Class
     * @param value 值
     * @param defaultValue 默认值
     * @return Enum
     */
    public static <E extends Enum<E>> E toEnum(Class<E> 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对象<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     *
     * @param clazz Enum的Class
     * @param value 值
     * @return Enum
     */
    public static <E extends Enum<E>> E toEnum(Class<E> clazz, Object value)
    {
        return toEnum(clazz, value, null);
    }
    /**
     * 转换为BigInteger<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<code>null</code><br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static BigInteger toBigInteger(Object value)
    {
        return toBigInteger(value, null);
    }
    /**
     * 转换为BigDecimal<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @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<br>
     * 如果给定的值为空,或者转换失败,返回默认值<br>
     * 转换失败不会报错
     *
     * @param value 被转换的值
     * @return 结果
     */
    public static BigDecimal toBigDecimal(Object value)
    {
        return toBigDecimal(value, null);
    }
    /**
     * 将对象转为字符串<br>
     * 1、Byte数组和ByteBuffer会被转换为对应字符串的数组 2、对象数组会调用Arrays.toString方法
     *
     * @param obj 对象
     * @return 字符串
     */
    public static String utf8Str(Object obj)
    {
        return str(obj, CharsetKit.CHARSET_UTF_8);
    }
    /**
     * 将对象转为字符串<br>
     * 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));
    }
    /**
     * 将对象转为字符串<br>
     * 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<Character> 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<Character> 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("^整$", "零元整");
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/text/StrFormatter.java
New file
@@ -0,0 +1,92 @@
package com.xinquan.common.core.text;
import com.xinquan.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 = '}';
    /**
     * 格式化字符串<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例:<br>
     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     *
     * @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();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/DateUtils.java
New file
@@ -0,0 +1,366 @@
package com.xinquan.common.core.utils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.poi.ss.usermodel.DateUtil;
import java.lang.management.ManagementFactory;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.util.*;
/**
 * 时间工具类
 *
 * @author ruoyi
 */
public class DateUtils extends org.apache.commons.lang3.time.DateUtils
{
    private static TimeZone tz = TimeZone.getTimeZone("GMT+8");
    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 endTime, Date startTime)
    {
        long nd = 1000 * 24 * 60 * 60;
        long nh = 1000 * 60 * 60;
        long nm = 1000 * 60;
        // long ns = 1000;
        // 获得两个时间的毫秒时间差异
        long diff = endTime.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());
    }
    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 较小的时间
     * @param bdate  较大的时间
     * @return 相差天数
     */
    public static int daysBetween(Date smdate, Date bdate) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(days));
    }
    /**
     * 得到系统日期
     *
     * @return
     */
    public static Date getDateTime() {
        TimeZone.setDefault(tz);
        return new Date();
    }
    /**
     * 字符串日期转Date yyyy-MM-dd HH:mm:ss
     *
     * @param dateStr
     * @return
     */
    public static Date getDate_str3(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(tz);
        if ("".equals(dateStr)) {
            dateStr = sdf.format(DateUtils.getDateTime());
        }
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    /**
     * 指定日期所在周的周一和周日时间
     *
     * @return 结果集
     */
    public static Map<String, Date> getWeekDate(Date date) {
        Map<String, Date> map = new HashMap<>(2);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        // 设置一个星期的第一天,按中国的习惯一个星期的第一天是星期一
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        // 获得当前日期是一个星期的第几天
        int dayWeek = cal.get(Calendar.DAY_OF_WEEK);
        if (dayWeek == 1) {
            dayWeek = 8;
        }
        // 根据日历的规则,给当前日期减去星期几与一个星期第一天的差值
        cal.add(Calendar.DATE, cal.getFirstDayOfWeek() - dayWeek);
        Date mondayDate = cal.getTime();
        cal.add(Calendar.DATE, 4 + cal.getFirstDayOfWeek());
        Date sundayDate = cal.getTime();
        map.put("first", mondayDate);
        map.put("last", sundayDate);
        return map;
    }
    /**
     * 指定日期所在月的第一天/最后一天时间
     *
     * @return 结果集
     */
    public static Map<String, Date> getMonthDate(Date date) {
        Map<String, Date> map = new HashMap<>(2);
        Calendar cal = Calendar.getInstance();
        //设置指定日期
        cal.setTime(date);
        //获取当月第一天日期
        int first = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, first);
        Date firstDay = cal.getTime();
        map.put("first", firstDay);
        //获取当月最后一天日期
        int last = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
        cal.set(Calendar.DAY_OF_MONTH, last);
        Date lastDay = cal.getTime();
        map.put("last", lastDay);
        return map;
    }
    /**
     * 指定日期所在年的第一天/最后一天时间
     *
     * @return 结果集
     */
    public static Map<String, Date> getYearDate(Date date) {
        Map<String, Date> map = new HashMap<>(2);
        Calendar cal = Calendar.getInstance();
        //设置指定日期
        cal.setTime(date);
        //获取本年第一天日期
        int first = cal.getActualMinimum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, first);
        Date firstDay = cal.getTime();
        map.put("first", firstDay);
        //获取本年最后一天日期
        int last = cal.getActualMaximum(Calendar.DAY_OF_YEAR);
        cal.set(Calendar.DAY_OF_YEAR, last);
        Date lastDay = cal.getTime();
        map.put("last", lastDay);
        return map;
    }
    /**
     * 分别获取日期中的年月日
     *
     * @param date 需要获取的日期
     * @return 结果集合
     */
    public static Map<String, String> getYearMonthDay(Date date) {
        String year = String.format("%tY", date);
        String month = String.format("%tm", date);
        String day = String.format("%td", date);
        Map<String, String> result = new HashMap<>(3);
        result.put("year", year);
        result.put("month", month);
        result.put("day", day);
        result.put("time", String.valueOf(date.getTime()));
        return result;
    }
    /**
     * Date转为LocalDateTime
     *
     * @param date 日期
     * @return LocalDateTime
     */
    public static LocalDateTime dateToLocalDateTime(Date date) {
        Instant instant = date.toInstant();
        ZoneId zoneId = ZoneId.systemDefault();
        return instant.atZone(zoneId).toLocalDateTime();
    }
    /**
     * LocalDateTime转Date
     *
     * @param dateTime 日期
     * @return Date
     */
    public static Date localDateTimeToDate(LocalDateTime dateTime) {
        ZoneId zoneId = ZoneId.systemDefault();
        ZonedDateTime zdt = dateTime.atZone(zoneId);
        return Date.from(zdt.toInstant());
    }
    /**
     * 获取当天的00:00:00
     *
     * @return
     */
    public static LocalDateTime getDayStart(LocalDateTime time) {
        return time.with(LocalTime.MIN);
    }
    /**
     * 获取当天的23:59:59
     *
     * @return
     */
    public static LocalDateTime getDayEnd(LocalDateTime time) {
        return time.with(LocalTime.MAX);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ExceptionUtil.java
New file
@@ -0,0 +1,39 @@
package com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ImportExcelUtil.java
New file
@@ -0,0 +1,41 @@
package com.xinquan.common.core.utils;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.xinquan.common.core.domain.R;
import com.xinquan.common.core.web.domain.AjaxResult;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.util.List;
/**
 * 导出返回信息
 */
@Slf4j
public class ImportExcelUtil {
    /**
     * @param errorLines   错误行数
     * @param successLines 成功行数
     * @param errorMessage 错误信息
     * @return
     * @throws IOException
     */
    public static R<String > importReturnMsg(int errorLines, int successLines, List<String> errorMessage) throws IOException {
        if (errorLines == 0) {
            return R.ok("共" + successLines + "行数据全部导入成功!");
        } else {
            JSONObject result = new JSONObject(5);
            int totalCount = successLines + errorLines;
            result.put("totalCount", totalCount);
            result.put("errorCount", errorLines);
            result.put("errorMessage", errorMessage);
            result.put("successCount", successLines);
            result.put("msg", "总上传行数:" + totalCount + ",已导入行数:" + successLines + ",错误行数:" + errorLines);
            return R.ok(JSON.toJSONString(result));
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/JwtUtils.java
New file
@@ -0,0 +1,123 @@
package com.xinquan.common.core.utils;
import java.util.Map;
import com.xinquan.common.core.constant.SecurityConstants;
import com.xinquan.common.core.constant.TokenConstants;
import com.xinquan.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<String, Object> 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), "");
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/PageUtils.java
New file
@@ -0,0 +1,35 @@
package com.xinquan.common.core.utils;
import com.github.pagehelper.PageHelper;
import com.xinquan.common.core.utils.sql.SqlUtil;
import com.xinquan.common.core.web.page.PageDomain;
import com.xinquan.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();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ServletUtils.java
New file
@@ -0,0 +1,333 @@
package com.xinquan.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.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.domain.R;
import com.xinquan.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<String, String[]> getParams(ServletRequest request)
    {
        final Map<String, String[]> map = request.getParameterMap();
        return Collections.unmodifiableMap(map);
    }
    /**
     * 获得所有请求参数
     *
     * @param request 请求对象{@link ServletRequest}
     * @return Map
     */
    public static Map<String, String> getParamMap(ServletRequest request)
    {
        Map<String, String> params = new HashMap<>();
        for (Map.Entry<String, String[]> 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<String, String> getHeaders(HttpServletRequest request)
    {
        Map<String, String> map = new LinkedCaseInsensitiveMap<>();
        Enumeration<String> 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<Void>
     */
    public static Mono<Void> webFluxResponseWriter(ServerHttpResponse response, Object value)
    {
        return webFluxResponseWriter(response, HttpStatus.OK, value, R.FAIL);
    }
    /**
     * 设置webflux模型响应
     *
     * @param response ServerHttpResponse
     * @param code 响应状态码
     * @param value 响应内容
     * @return Mono<Void>
     */
    public static Mono<Void> 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<Void>
     */
    public static Mono<Void> 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<Void>
     */
    public static Mono<Void> 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));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/SpringUtils.java
New file
@@ -0,0 +1,114 @@
package com.xinquan.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> T getBean(String name) throws BeansException
    {
        return (T) beanFactory.getBean(name);
    }
    /**
     * 获取类型为requiredType的对象
     *
     * @param clz
     * @return
     * @throws org.springframework.beans.BeansException
     *
     */
    public static <T> T getBean(Class<T> 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> T getAopProxy(T invoker)
    {
        return (T) AopContext.currentProxy();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/StringUtils.java
New file
@@ -0,0 +1,561 @@
package com.xinquan.common.core.utils;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.springframework.util.AntPathMatcher;
import com.xinquan.common.core.constant.Constants;
import com.xinquan.common.core.text.StrFormatter;
/**
 * 字符串工具类
 *
 * @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> 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;
    }
    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例:<br>
     * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     *
     * @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);
    }
    /**
     * 判断给定的collection列表中是否包含数组array 判断给定的数组array中是否包含给定的元素value
     *
     * @param collection 给定的集合
     * @param array 给定的数组
     * @return boolean 结果
     */
    public static boolean containsAny(Collection<String> 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<String> 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> 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();
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/WebUtils.java
New file
@@ -0,0 +1,169 @@
package com.xinquan.common.core.utils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.HashMap;
import java.util.Map;
/**
 * web工具类
 *
 * @author liheng
 */
public final class WebUtils extends org.springframework.web.util.WebUtils {
    /**
     * 当前请求
     */
    public static HttpServletRequest request() {
        return contextHolder() == null ? null : contextHolder().getRequest();
    }
    /**
     * 当前响应
     */
    public static HttpServletResponse response() {
        return contextHolder() == null ? null : contextHolder().getResponse();
    }
    /**
     * 当前session
     */
    public static HttpSession session() {
        return request() == null ? null : request().getSession();
    }
    /**
     * 当前ServletRequest
     */
    public static ServletRequestAttributes contextHolder() {
        return (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    }
    /**
     * 判断请求是否为 AJAX
     *
     * @param request 当前请求
     */
    public static boolean isAjax(HttpServletRequest request) {
        return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
    }
    /**
     * 获取操作系统,浏览器及浏览器版本信息
     *
     * @param request
     * @return
     */
    public static Map<String, String> getOsAndBrowserInfo(HttpServletRequest request) {
        Map<String, String> map = new HashMap<>(2);
        String browserDetails = request.getHeader("User-Agent");
        String userAgent = browserDetails;
        String user = userAgent.toLowerCase();
        String os = "";
        String browser = "";
        //=================OS Info=======================
        if (userAgent.toLowerCase().contains("windows")) {
            os = "Windows";
        } else if (userAgent.toLowerCase().contains("mac")) {
            os = "Mac";
        } else if (userAgent.toLowerCase().contains("x11")) {
            os = "Unix";
        } else if (userAgent.toLowerCase().contains("android")) {
            os = "Android";
        } else if (userAgent.toLowerCase().contains("iphone")) {
            os = "IPhone";
        } else {
            os = "UnKnown, More-Info: " + userAgent;
        }
        //===============Browser===========================
        if (user.contains("edge")) {
            browser = (userAgent.substring(userAgent.indexOf("Edge")).split(" ")[0]).replace("/", "-");
        } else if (user.contains("msie")) {
            String substring = userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0];
            browser = substring.split(" ")[0].replace("MSIE", "IE") + "-" + substring.split(" ")[1];
        } else if (user.contains("safari") && user.contains("version")) {
            browser = (userAgent.substring(userAgent.indexOf("Safari")).split(" ")[0]).split("/")[0]
                    + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
        } else if (user.contains("opr") || user.contains("opera")) {
            if (user.contains("opera")) {
                browser = (userAgent.substring(userAgent.indexOf("Opera")).split(" ")[0]).split("/")[0]
                        + "-" + (userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
            } else if (user.contains("opr")) {
                browser = ((userAgent.substring(userAgent.indexOf("OPR")).split(" ")[0]).replace("/", "-"))
                        .replace("OPR", "Opera");
            }
        } else if (user.contains("chrome")) {
            browser = (userAgent.substring(userAgent.indexOf("Chrome")).split(" ")[0]).replace("/", "-");
        } else if ((user.contains("mozilla/7.0")) || (user.contains("netscape6")) ||
                (user.contains("mozilla/4.7")) || (user.contains("mozilla/4.78")) ||
                (user.contains("mozilla/4.08")) || (user.contains("mozilla/3"))) {
            browser = "Netscape-?";
        } else if (user.contains("firefox")) {
            browser = (userAgent.substring(userAgent.indexOf("Firefox")).split(" ")[0]).replace("/", "-");
        } else if (user.contains("rv")) {
            String IEVersion = (userAgent.substring(userAgent.indexOf("rv")).split(" ")[0]).replace("rv:", "-");
            browser = "IE" + IEVersion.substring(0, IEVersion.length() - 1);
        } else {
            browser = "UnKnown, More-Info: " + userAgent;
        }
        map.put("os", os);
        map.put("browser", browser);
        return map;
    }
    /**
     * 读取cookie
     *
     * @param name cookie name
     * @return cookie value
     */
    public String getCookieVal(String name) {
        return getCookieVal(request(), name);
    }
    /**
     * 读取cookie
     *
     * @param request HttpServletRequest
     * @param name    cookie name
     * @return cookie value
     */
    public String getCookieVal(HttpServletRequest request, String name) {
        Cookie cookie = getCookie(request, name);
        return cookie != null ? cookie.getValue() : null;
    }
    /**
     * 清除 某个指定的cookie
     *
     * @param response HttpServletResponse
     * @param key      cookie key
     */
    public void removeCookie(HttpServletResponse response, String key) {
        setCookie(response, key, null, 0);
    }
    /**
     * 设置cookie
     *
     * @param response        HttpServletResponse
     * @param name            cookie name
     * @param value           cookie value
     * @param maxAgeInSeconds maxage
     */
    public void setCookie(HttpServletResponse response, String name, String value, int maxAgeInSeconds) {
        Cookie cookie = new Cookie(name, value);
        cookie.setPath("/");
        cookie.setMaxAge(maxAgeInSeconds);
        //cookie.setHttpOnly(true);
        response.addCookie(cookie);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/bean/BeanUtils.java
New file
@@ -0,0 +1,110 @@
package com.xinquan.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<Method> getSetterMethods(Object obj)
    {
        // setter方法列表
        List<Method> setterMethods = new ArrayList<Method>();
        // 获取所有方法
        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<Method> getGetterMethods(Object obj)
    {
        // getter方法列表
        List<Method> getterMethods = new ArrayList<Method>();
        // 获取所有方法
        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方法名中的属性名是否相等。<br>
     * 如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));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/bean/BeanValidators.java
New file
@@ -0,0 +1,24 @@
package com.xinquan.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<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
        if (!constraintViolations.isEmpty())
        {
            throw new ConstraintViolationException(constraintViolations);
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/FileTypeUtils.java
New file
@@ -0,0 +1,95 @@
package com.xinquan.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
{
    /**
     * 获取文件类型
     * <p>
     * 例如: ruoyi.txt, 返回: txt
     *
     * @param file 文件名
     * @return 后缀(不含".")
     */
    public static String getFileType(File file)
    {
        if (null == file)
        {
            return StringUtils.EMPTY;
        }
        return getFileType(file.getName());
    }
    /**
     * 获取文件类型
     * <p>
     * 例如: 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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/FileUtils.java
New file
@@ -0,0 +1,253 @@
package com.xinquan.common.core.utils.file;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import com.xinquan.common.core.utils.StringUtils;
/**
 * 文件处理工具类
 *
 * @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;
        }
        // 判断是否在允许下载的文件规则内
        return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
    }
    /**
     * 下载文件名重新编码
     *
     * @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)文件分隔符<br>
     * 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");
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/ImageUtils.java
New file
@@ -0,0 +1,84 @@
package com.xinquan.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);
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/file/MimeTypeUtils.java
New file
@@ -0,0 +1,59 @@
package com.xinquan.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 "";
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/html/EscapeUtil.java
New file
@@ -0,0 +1,167 @@
package com.xinquan.common.core.utils.html;
import com.xinquan.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['\''] = "&#039;".toCharArray(); // 单引号
        TEXT['"'] = "&#34;".toCharArray(); // 双引号
        TEXT['&'] = "&#38;".toCharArray(); // &符
        TEXT['<'] = "&#60;".toCharArray(); // 小于号
        TEXT['>'] = "&#62;".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 = "<script>alert(1);</script>";
        String escape = EscapeUtil.escape(html);
        // String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>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));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/html/HTMLFilter.java
New file
@@ -0,0 +1,570 @@
package com.xinquan.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<String, Pattern> P_REMOVE_PAIR_BLANKS = new ConcurrentHashMap<>();
    private static final ConcurrentMap<String, Pattern> P_REMOVE_SELF_BLANKS = new ConcurrentHashMap<>();
    /**
     * set of allowed html elements, along with allowed attributes for each element
     **/
    private final Map<String, List<String>> vAllowed;
    /**
     * counts of open tags for each (allowable) html element
     **/
    private final Map<String, Integer> vTagCounts = new HashMap<>();
    /**
     * html elements which must always be self-closing (e.g. "<img />")
     **/
    private final String[] vSelfClosingTags;
    /**
     * html elements which must always have separate opening and closing tags (e.g. "<b></b>")
     **/
    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. "<b></b>" or "<b />")
     **/
    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. "<b text </b>"
     * becomes "<b> text </b>"). If set to false, unbalanced angle brackets will be html escaped.
     */
    private final boolean alwaysMakeTags;
    /**
     * Default constructor.
     */
    public HTMLFilter()
    {
        vAllowed = new HashMap<>();
        final ArrayList<String> a_atts = new ArrayList<>();
        a_atts.add("href");
        a_atts.add("target");
        vAllowed.put("a", a_atts);
        final ArrayList<String> 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<String> 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<String, Object> 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<String, List<String>>) 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, "&amp;", result);
        result = regexReplace(P_QUOTE, "&quot;", result);
        result = regexReplace(P_LEFT_ARROW, "&lt;", result);
        result = regexReplace(P_RIGHT_ARROW, "&gt;", 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("<!--" + htmlSpecialChars(match) + "-->"));
        }
        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, "&lt;$1", s);
            s = regexReplace(P_STRAY_RIGHT_ARROW, "$1$2&gt;<", 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("</").append(key).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[^>]*)?></" + tag + ">"));
            }
            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 "</" + name + ">";
                    }
                }
            }
        }
        // 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<String> paramNames = new ArrayList<>();
                final List<String> 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); // (<|$)
                // 不替换双引号为&quot;,防止json格式无效 regexReplace(P_QUOTE, "&quot;", 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 : "&amp;" + 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));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/ip/IpUtils.java
New file
@@ -0,0 +1,382 @@
package com.xinquan.common.core.utils.ip;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest;
import com.xinquan.common.core.utils.ServletUtils;
import com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/obs/OBSUtil.java
New file
@@ -0,0 +1,43 @@
package com.xinquan.common.core.utils.obs;
import com.obs.services.ObsClient;
import com.obs.services.model.PutObjectRequest;
import com.obs.services.model.PutObjectResult;
import java.io.InputStream;
/**
 * 对象存储上传
 * @author zhibing.pu
 * @date 2023/3/15 11:32
 */
public class OBSUtil {
    public static String endPoint = "https://obs.cn-southwest-2.myhuaweicloud.com";
    public static String ak = "ONCVMOIXDX55ADAU5MFS";
    public static String sk = "3uuS3p3rcw2WYSpFVPveIGm7wVvx5OtoCNhbBv3n";
    public static String bucketname = "yixingtong";
    /**
     * 上传文件
     * @param inputStream
     * @param objectKey
     * @return
     */
    public static String  putObjectToBucket(InputStream inputStream, String objectKey) {
        try {
            // 创建ObsClient实例
            ObsClient obsClient = new ObsClient(ak, sk, endPoint);
            // 待上传的本地文件路径,需要指定到具体的文件名
            PutObjectRequest request = new PutObjectRequest();
            request.setBucketName(bucketname);
            request.setObjectKey(objectKey);
            request.setInput(inputStream);
            PutObjectResult putObjectResult = obsClient.putObject(request);
            return putObjectResult.getObjectUrl();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/ArrayUtils.java
New file
@@ -0,0 +1,53 @@
package com.xinquan.common.core.utils.page;
import cn.hutool.core.util.ArrayUtil;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 数组工具类
 * @ClassName ArrayUtils
 * @author wusongsong
 * @since 2022/7/10 12:02
 * @version 1.0.0
 **/
public class ArrayUtils extends ArrayUtil {
    /**
     * 将源数组转换成指定类型的列表
     *
     * @param originList  原始列表
     * @param targetClazz 转换后列表元素的类型
     * @param <R>         原始列表元素的类型
     * @param <T>         目标列表元素的类型
     * @return 目标类型的集合
     */
    public static <R, T> List<T> convert(R[] originList, Class<T> targetClazz) {
       return convert(originList, targetClazz, null);
    }
    /**
     * 将源数组转换成指定类型的列表
     *
     * @param originList  原始列表
     * @param targetClazz 转换后列表元素的类型
     * @param convert     转换特殊字段接口
     * @param <R>         原始列表元素的类型
     * @param <T>         目标列表元素的类型
     * @return 目标类型的集合
     */
    public static <R, T> List<T> convert(R[] originList, Class<T> targetClazz, Convert<R, T> convert) {
        if (isEmpty(originList)) {
            return null;
        }
        return Arrays.stream(originList)
                .map(origin -> BeanUtils.copyBean(origin, targetClazz, convert))
                .collect(Collectors.toList());
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/BeanUtils.java
New file
@@ -0,0 +1,58 @@
package com.xinquan.common.core.utils.page;
import cn.hutool.core.bean.BeanUtil;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 继承自 hutool 的BeanUtil,增加了bean转换时自定义转换器的功能
 */
public class BeanUtils extends BeanUtil {
    /**
     * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
     *
     * @param source  原对象
     * @param clazz   目标对象的class
     * @param convert 转换器
     * @param <R>     原对象类型
     * @param <T>     目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz, Convert<R, T> convert) {
        T target = copyBean(source, clazz);
        if (convert != null) {
            convert.convert(source, target);
        }
        return target;
    }
    /**
     * 将原对象转换成目标对象,对于字段不匹配的字段可以使用转换器处理
     *
     * @param source  原对象
     * @param clazz   目标对象的class
     * @param <R>     原对象类型
     * @param <T>     目标对象类型
     * @return 目标对象
     */
    public static <R, T> T copyBean(R source, Class<T> clazz){
        if (source == null) {
            return null;
        }
        return toBean(source, clazz);
    }
    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return copyToList(list, clazz);
    }
    public static <R, T> List<T> copyList(List<R> list, Class<T> clazz, Convert<R, T> convert) {
        if (list == null || list.size() == 0) {
            return CollUtils.emptyList();
        }
        return list.stream().map(r -> copyBean(r, clazz, convert)).collect(Collectors.toList());
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/Checker.java
New file
@@ -0,0 +1,18 @@
package com.xinquan.common.core.utils.page;
/**
 * 实现后在接口访问时如果接口实现了这个接口
 * 会被自动自行接口check进行校验
 **/
public interface Checker<T> {
    /**
     * 用于实现validation不能校验的数据逻辑
     */
    default void check(){
    }
    default void check(T data){
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/CollUtils.java
New file
@@ -0,0 +1,144 @@
package com.xinquan.common.core.utils.page;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.IterUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
 * 继承自 hutool 的集合工具类
 */
public class CollUtils extends CollectionUtil {
    public static <T> List<T> emptyList() {
        return Collections.emptyList();
    }
    public static <T> Set<T> emptySet() {
        return Collections.emptySet();
    }
    public static <K,V> Map<K, V> emptyMap() {
        return Collections.emptyMap();
    }
    public static <T> Set<T> singletonSet(T t) {
        return Collections.singleton(t);
    }
    public static <T> List<T> singletonList(T t) {
        return Collections.singletonList(t);
    }
    public static List<Integer> convertToInteger(List<String> originList){
        return CollUtils.isNotEmpty(originList) ? originList.stream().map(NumberUtils::parseInt).collect(Collectors.toList()) : null;
    }
    public static List<Long> convertToLong(List<String> originLIst){
        return CollUtils.isNotEmpty(originLIst) ? originLIst.stream().map(NumberUtils::parseLong).collect(Collectors.toList()) : null;
    }
    /**
     * 以 conjunction 为分隔符将集合转换为字符串 如果集合元素为数组、Iterable或Iterator,则递归组合其为字符串
     * @param collection 集合
     * @param conjunction 分隔符
     * @param <T> 集合元素类型
     * @return 连接后的字符串
     * See Also: IterUtil.join(Iterator, CharSequence)
     */
    public static <T> String join(Collection<T> collection, CharSequence conjunction) {
        if (null == collection || collection.isEmpty()) {
            return null;
        }
        return IterUtil.join(collection.iterator(), conjunction);
    }
    public static <T> String joinIgnoreNull(Collection<T> collection, CharSequence conjunction) {
        if (null == collection || collection.isEmpty()) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        for (T t : collection) {
            if(t == null) continue;
            sb.append(t).append(",");
        }
        if(sb.length() <= 0){
            return null;
        }
        return sb.deleteCharAt(sb.length() - 1).toString();
    }
    /**
     * 集合校验逻辑
     *
     * @param data 要校验的集合
     * @param checker 校验器
     * @param <T> 集合元素类型
     */
    public static  <T> void  check(List<T> data, Checker<T> checker){
        if(data == null){
            return;
        }
        for (T t : data){
            checker.check(t);
        }
    }
    /**
     * 集合校验逻辑
     *
     * @param data 要校验的集合
     * @param <T> 集合元素类型
     */
    public static  <T extends Checker<T>> void  check(List<T> data){
        if(data == null){
            return;
        }
        for (T t : data){
            t.check();
        }
    }
    /**
     * 将元素加入到集合中,为null的过滤掉
     *
     * @param list 集合
     * @param data 要添加的数据
     * @param <T> 元素类型
     */
    public static <T> void add(Collection<T> list, T... data) {
        if (list == null || ArrayUtils.isEmpty(data)) {
            return;
        }
        for (T t : data) {
            if (ObjectUtils.isNotEmpty(t)) {
                list.add(t);
            }
        }
    }
    //将两个集合出现次数相加
    public static Map<Long, Integer> union(Map<Long, Integer> map1, Map<Long, Integer> map2) {
        if (CollUtils.isEmpty(map1)) {
            return map2;
        } else if (CollUtils.isEmpty(map2)) {
            return map1;
        }
        for (Map.Entry<Long, Integer> entry : map1.entrySet()) {
            Integer num = map2.get(entry.getKey());
            map2.put(entry.getKey(), NumberUtils.null2Zero(num) + entry.getValue());
        }
        return map2;
    }
    public static <T,R> R getFiledOfFirst(List<T> list, Function<T, R> function) {
        if (CollUtils.isEmpty(list)) {
            return null;
        }
        return function.apply(list.get(0));
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/Convert.java
New file
@@ -0,0 +1,8 @@
package com.xinquan.common.core.utils.page;
/**
 * 对原对象进行计算,设置到目标对象中
 **/
public interface Convert<R,T>{
    void convert(R origin, T target);
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/NumberUtils.java
New file
@@ -0,0 +1,147 @@
package com.xinquan.common.core.utils.page;
import cn.hutool.core.util.NumberUtil;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
public class NumberUtils extends NumberUtil {
    /**
     * 如果number为空,将number转换为0,否则原数字返回
     *
     * @param number 原数值
     * @return 整型数字,0或原数字
     */
    public static Integer null2Zero(Integer number){
        return number == null ? 0 : number;
    }
    /**
     * 如果number为空,将number转换为0,否则原数字返回
     *
     * @param number 原数值
     * @return 整型数字,0或原数字
     */
    public static Double null2Zero(Double number){
        return number == null ? 0 : number;
    }
    /**
     * 如果number为空,将number转换为0L,否则原数字返回
     *
     * @param number  原数值
     * @return 长整型数字,0L或原数字
     */
    public static Long null2Zero(Long number){
        return number == null ? 0L : number;
    }
    public static Double setScale(Double number) {
        return new BigDecimal(number)
                .setScale(2, BigDecimal.ROUND_HALF_UP)
                .doubleValue();
    }
    /**
     * 比较两个数字是否相同,
     * @param number1 数值1
     * @param number2 数值2
     * @return 是否一致
     */
    public static boolean equals(Integer number1, Integer number2) {
        if(number1 == null || number2 == null){
            return false;
        }
        return number1.equals(number2);
    }
    /**
     * 数字除法保留指定小数位
     * @param num1 被除数
     * @param num2 除数
     * @param scale 小数点位数
     * @return 结果
     */
    public static Double divToDouble(Integer num1, Integer num2, int scale){
        if(num2 == null || num2 ==0 || num1 == null || num1 == 0) {
            return 0d;
        }
        return div(num1, num2, scale).doubleValue();
    }
    public static  Double max(List<Double> data){
        if(CollUtils.isEmpty(data)){
            return null;
        }
        return data.stream()
                .max(Comparator.comparingDouble(num -> num))
                .orElse(0d);
    }
    public static  Double min(List<Double> data){
        if(CollUtils.isEmpty(data)){
            return null;
        }
        return data.stream()
                .min(Comparator.comparingDouble(num -> num))
                .orElse(0d);
    }
    public static Double average(List<Double> data){
        if(CollUtils.isEmpty(data)){
            return 0d;
        }
        return data.stream()
                .collect(Collectors.averagingDouble(Double::doubleValue));
    }
    public static Integer toInt(Object obj) {
        return obj == null ? null
                : obj instanceof Integer
                ? (int) obj : null;
    }
    /**
     * 取绝对值,如果为null,返回0
     * @param number 数值
     * @return 绝对值
     */
    public static int abs(Integer number) {
        return number == null
                ? 0
                : Math.abs(number);
    }
    /**
     * 数字格式化字符串,不足位数补0
     *
     * @param originNumber 原始数字
     * @param digit 数字位数
     * @return 字符串
     */
    public static String  repair0(Integer originNumber, Integer digit){
        StringBuilder number = new StringBuilder(originNumber + "");
        while (number.length() < digit) {
            number.insert(0, "0");
        }
        return number.toString();
    }
    public static String scaleToStr(Integer num, int offset) {
        // 1.计算位数
        int m = (int) Math.pow(10, offset);
        // 2.计算商
        int s = num / m;
        // 3.计算余数
        int y = num % m;
        if (y == 0) {
            return Integer.toString(s);
        }
        // 2.计算余数
        return s + "." + y;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/ObjectUtils.java
New file
@@ -0,0 +1,83 @@
package com.xinquan.common.core.utils.page;
import cn.hutool.core.util.ObjectUtil;
import java.lang.reflect.Field;
import java.math.BigDecimal;
/**
 * Object操作工具
 **/
public class ObjectUtils extends ObjectUtil {
    /**
     * 为object设置默认值,对target中的基本类型进行默认值初始化,
     * 为null的对象不操作
     *
     * @param target 需要初始化的对象
     */
    public static void setDefault(Object target) {
        if (target == null) {
            return;
        }
        Class<?> clazz = target.getClass();
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            setDefault(field, target);
        }
    }
    /**
     * 给某个字段设置为默认值
     *
     * @param field
     * @param target
     */
    private static void setDefault(Field field, Object target) {
        field.setAccessible(true);
        try {
            Object value = field.get(target);
            if (value != null) {
                return;
            }
            String type = field.getGenericType().toString();
            Object defaultValue;
            switch (type) {
                case "class java.lang.String":
                case "class java.lang.Character":
                    defaultValue = "";
                    break;
                case "class java.lang.Double":
                    defaultValue = 0.0d;
                    break;
                case "class java.lang.Long":
                    defaultValue = 0L;
                    break;
                case "class java.lang.Short":
                    defaultValue = (short) 0;
                    break;
                case "class java.lang.Integer":
                    defaultValue = 0;
                    break;
                case "class java.lang.Float":
                    defaultValue = 0f;
                    break;
                case "class java.lang.Byte":
                    defaultValue = (byte) 0;
                    break;
                case "class java.math.BigDecimal":
                    defaultValue = BigDecimal.ZERO;
                    break;
                case "class java.lang.Boolean":
                    defaultValue = Boolean.FALSE;
                    break;
                default:
                    defaultValue = null;
            }
            field.set(target, defaultValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/page/PageDTO.java
New file
@@ -0,0 +1,70 @@
package com.xinquan.common.core.utils.page;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@ApiModel(description = "分页结果")
public class PageDTO<T> {
    @ApiModelProperty("总条数")
    protected Long total;
    @ApiModelProperty("总页码数")
    protected Long pages;
    @ApiModelProperty("当前页数据")
    protected List<T> list;
    public static <T> PageDTO<T> empty(Long total, Long pages) {
        return new PageDTO<>(total, pages, CollUtils.emptyList());
    }
    public static <T> PageDTO<T> empty(Page<?> page) {
        return new PageDTO<>(page.getTotal(), page.getPages(), CollUtils.emptyList());
    }
    public static <T> PageDTO<T> of(Page<T> page) {
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(), page.getRecords());
    }
    public static <T,R> PageDTO<T> of(Page<R> page, Function<R, T> mapper) {
        if(page == null){
            return new PageDTO<>();
        }
        if (CollUtils.isEmpty(page.getRecords())) {
            return empty(page);
        }
        return new PageDTO<>(page.getTotal(), page.getPages(),
                page.getRecords().stream().map(mapper).collect(Collectors.toList()));
    }
    public static <T> PageDTO<T> of(Page<?> page, List<T> list) {
        return new PageDTO<>(page.getTotal(), page.getPages(), list);
    }
    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz) {
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz));
    }
    public static <T, R> PageDTO<T> of(Page<R> page, Class<T> clazz, Convert<R, T> convert) {
        return new PageDTO<>(page.getTotal(), page.getPages(), BeanUtils.copyList(page.getRecords(), clazz, convert));
    }
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public boolean isEmpty(){
        return list == null || list.size() == 0;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/poi/ExcelHandlerAdapter.java
New file
@@ -0,0 +1,19 @@
package com.xinquan.common.core.utils.poi;
/**
 * Excel数据格式处理适配器
 *
 * @author ruoyi
 */
public interface ExcelHandlerAdapter
{
    /**
     * 格式化
     *
     * @param value 单元格数据值
     * @param args excel注解args参数组
     *
     * @return 处理后的值
     */
    Object format(Object value, String[] args);
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/poi/ExcelUtil.java
New file
@@ -0,0 +1,1487 @@
package com.xinquan.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.xinquan.common.core.annotation.Excel;
import com.xinquan.common.core.annotation.Excel.ColumnType;
import com.xinquan.common.core.annotation.Excel.Type;
import com.xinquan.common.core.annotation.Excels;
import com.xinquan.common.core.text.Convert;
import com.xinquan.common.core.utils.DateUtils;
import com.xinquan.common.core.utils.StringUtils;
import com.xinquan.common.core.utils.file.FileTypeUtils;
import com.xinquan.common.core.utils.file.ImageUtils;
import com.xinquan.common.core.utils.reflect.ReflectUtils;
/**
 * Excel相关处理
 *
 * @author ruoyi
 */
public class ExcelUtil<T>
{
    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<String, CellStyle> styles;
    /**
     * 导入导出数据列表
     */
    private List<T> list;
    /**
     * 注解列表
     */
    private List<Object[]> fields;
    /**
     * 当前行号
     */
    private int rownum;
    /**
     * 标题
     */
    private String title;
    /**
     * 最大高度
     */
    private short maxHeight;
    /**
     * 合并后最后行数
     */
    private int subMergedLastRowNum = 0;
    /**
     * 合并后开始行数
     */
    private int subMergedFirstRowNum = 1;
    /**
     * 对象的子列表方法
     */
    private Method subMethod;
    /**
     * 对象的子列表属性
     */
    private List<Field> subFields;
    /**
     * 统计列表
     */
    private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
    /**
     * 数字格式
     */
    private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
    /**
     * 实体对象
     */
    public Class<T> clazz;
    /**
     * 需要排除列属性
     */
    public String[] excludeFields;
    public ExcelUtil(Class<T> clazz)
    {
        this.clazz = clazz;
    }
    /**
     * 隐藏Excel中列属性
     *
     * @param fields 列属性名 示例[单个"name"/多个"id","name"]
     * @throws Exception
     */
    public void hideColumn(String... fields)
    {
        this.excludeFields = fields;
    }
    public void init(List<T> list, String sheetName, String title, Type type)
    {
        if (list == null)
        {
            list = new ArrayList<T>();
        }
        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<T> importExcel(InputStream is) throws Exception
    {
        return importExcel(is, 0);
    }
    /**
     * 对excel表单默认第一个索引名转换成list
     *
     * @param is 输入流
     * @param titleNum 标题占用行数
     * @return 转换后集合
     */
    public List<T> importExcel(InputStream is, int titleNum) throws Exception
    {
        return importExcel(StringUtils.EMPTY, is, titleNum);
    }
    /**
     * 对excel表单指定表格索引名转换成list
     *
     * @param sheetName 表格索引名
     * @param titleNum 标题占用行数
     * @param is 输入流
     * @return 转换后集合
     */
    public List<T> importExcel(String sheetName, InputStream is, int titleNum) throws Exception
    {
        this.type = Type.IMPORT;
        this.wb = WorkbookFactory.create(is);
        List<T> list = new ArrayList<T>();
        // 如果指定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<String, Integer> cellMap = new HashMap<String, Integer>();
            // 获取表头
            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<Object[]> fields = this.getFields();
            Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
            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<Integer, Object[]> 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<T> 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<T> 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<Field> 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<String, CellStyle> createStyles(Workbook wb)
    {
        // 写入各条记录,每条记录对应excel表中的一行
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        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<String, CellStyle> annotationHeaderStyles(Workbook wb, Map<String, CellStyle> styles)
    {
        Map<String, CellStyle> headerStyles = new HashMap<String, CellStyle>();
        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<String, CellStyle> annotationDataStyles(Workbook wb)
    {
        Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
        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<Integer> 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<Object[]> getFields()
    {
        List<Object[]> fields = new ArrayList<Object[]>();
        List<Field> 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 (!ArrayUtils.contains(this.excludeFields, field.getName() + "." + attr.targetAttr())
                                && (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<Object>();
        }
        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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/reflect/ReflectUtils.java
New file
@@ -0,0 +1,410 @@
package com.xinquan.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.xinquan.common.core.text.Convert;
import com.xinquan.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> 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 <E> 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> 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 <E> 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> 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> 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 <T> Class<T> 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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/sign/Base64.java
New file
@@ -0,0 +1,291 @@
package com.xinquan.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;
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/sql/SqlUtil.java
New file
@@ -0,0 +1,61 @@
package com.xinquan.common.core.utils.sql;
import com.xinquan.common.core.exception.UtilException;
import com.xinquan.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注入风险");
            }
        }
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/IdUtils.java
New file
@@ -0,0 +1,49 @@
package com.xinquan.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);
    }
}
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/Seq.java
New file
@@ -0,0 +1,86 @@
package com.xinquan.common.core.utils.uuid;
import java.util.concurrent.atomic.AtomicInteger;
import com.xinquan.common.core.utils.DateUtils;
import com.xinquan.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";
    /**
     * 获取通用序列号
     *
     * @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);
    }
}
Diff truncated after the above file
xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/utils/uuid/UUID.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/controller/BaseController.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/AjaxResult.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseEntity.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/BaseModel.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/domain/TreeEntity.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/BasePage.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/PageDomain.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/PageInfo.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/TableDataInfo.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/web/page/TableSupport.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/xss/Xss.java xinquan-common/xinquan-common-core/src/main/java/com/xinquan/common/core/xss/XssValidator.java xinquan-common/xinquan-common-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-common/xinquan-common-datascope/pom.xml xinquan-common/xinquan-common-datascope/src/main/java/com/xinquan/common/datascope/annotation/DataScope.java xinquan-common/xinquan-common-datascope/src/main/java/com/xinquan/common/datascope/aspect/DataScopeAspect.java xinquan-common/xinquan-common-datascope/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-common/xinquan-common-datasource/pom.xml xinquan-common/xinquan-common-datasource/src/main/java/com/xinquan/common/datasource/annotation/Master.java xinquan-common/xinquan-common-datasource/src/main/java/com/xinquan/common/datasource/annotation/Slave.java xinquan-common/xinquan-common-log/pom.xml xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/annotation/Log.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/aspect/LogAspect.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/BusinessStatus.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/BusinessType.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/enums/OperatorType.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/filter/PropertyPreExcludeFilter.java xinquan-common/xinquan-common-log/src/main/java/com/xinquan/common/log/service/AsyncLogService.java xinquan-common/xinquan-common-log/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-common/xinquan-common-redis/pom.xml xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/configure/FastJson2JsonRedisSerializer.java xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/configure/RedisConfig.java xinquan-common/xinquan-common-redis/src/main/java/com/xinquan/common/redis/service/RedisService.java xinquan-common/xinquan-common-redis/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-common/xinquan-common-seata/pom.xml xinquan-common/xinquan-common-security/pom.xml xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableCustomConfig.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/EnableRyFeignClients.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/InnerAuth.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/Logical.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresLogin.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresPermissions.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/annotation/RequiresRoles.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/aspect/InnerAuthAspect.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/aspect/PreAuthorizeAspect.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/auth/AuthLogic.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/auth/AuthUtil.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/ApplicationConfig.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/JacksonConfig.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/LocalDateTimeSerializerConfig.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/config/WebMvcConfig.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/feign/FeignAutoConfiguration.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/feign/FeignRequestInterceptor.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/handler/GlobalExceptionHandler.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/interceptor/HeaderInterceptor.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/service/TokenService.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/utils/DictUtils.java xinquan-common/xinquan-common-security/src/main/java/com/xinquan/common/security/utils/SecurityUtils.java xinquan-common/xinquan-common-security/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-common/xinquan-common-swagger/pom.xml xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/annotation/EnableCustomSwagger2.java xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerAutoConfiguration.java xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerBeanPostProcessor.java xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerProperties.java xinquan-common/xinquan-common-swagger/src/main/java/com/xinquan/common/swagger/config/SwaggerWebConfiguration.java xinquan-common/xinquan-common-swagger/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports xinquan-gateway/pom.xml xinquan-gateway/src/main/java/com/xinquan/gateway/XinQuanGatewayApplication.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/CaptchaConfig.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/GatewayConfig.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/KaptchaTextCreator.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/RouterFunctionConfiguration.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/SwaggerProvider.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/CaptchaProperties.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/IgnoreWhiteProperties.java xinquan-gateway/src/main/java/com/xinquan/gateway/config/properties/XssProperties.java xinquan-gateway/src/main/java/com/xinquan/gateway/filter/AuthFilter.java xinquan-gateway/src/main/java/com/xinquan/gateway/filter/BlackListUrlFilter.java xinquan-gateway/src/main/java/com/xinquan/gateway/filter/CacheRequestFilter.java xinquan-gateway/src/main/java/com/xinquan/gateway/filter/ValidateCodeFilter.java xinquan-gateway/src/main/java/com/xinquan/gateway/filter/XssFilter.java xinquan-gateway/src/main/java/com/xinquan/gateway/handler/GatewayExceptionHandler.java xinquan-gateway/src/main/java/com/xinquan/gateway/handler/SentinelFallbackHandler.java xinquan-gateway/src/main/java/com/xinquan/gateway/handler/SwaggerHandler.java xinquan-gateway/src/main/java/com/xinquan/gateway/handler/ValidateCodeHandler.java xinquan-gateway/src/main/java/com/xinquan/gateway/service/ValidateCodeService.java xinquan-gateway/src/main/java/com/xinquan/gateway/service/impl/ValidateCodeServiceImpl.java xinquan-gateway/src/main/resources/banner.txt xinquan-gateway/src/main/resources/logback.xml xinquan-modules/pom.xml xinquan-modules/xinquan-course/pom.xml xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/XinQuanCourseApplication.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseCategoryController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseChapterController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientCourseController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/client/ClientTutorSpecialColumnCourseController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseCategoryController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseChapterController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtCourseController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtTutorSpecialColumnController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/controller/management/MgtTutorSpecialColumnCourseController.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/Course.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseCategory.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/CourseChapter.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumn.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/domain/TutorSpecialColumnCourse.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseCategoryMapper.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseChapterMapper.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/CourseMapper.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/TutorSpecialColumnCourseMapper.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/mapper/TutorSpecialColumnMapper.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseCategoryService.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseChapterService.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/CourseService.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/TutorSpecialColumnCourseService.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/TutorSpecialColumnService.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseCategoryServiceImpl.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseChapterServiceImpl.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/CourseServiceImpl.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/TutorSpecialColumnCourseServiceImpl.java xinquan-modules/xinquan-course/src/main/java/com/xinquan/course/service/impl/TutorSpecialColumnServiceImpl.java xinquan-modules/xinquan-course/src/main/resources/banner.txt xinquan-modules/xinquan-course/src/main/resources/logback.xml xinquan-modules/xinquan-course/src/main/resources/mybatis-config.xml xinquan-modules/xinquan-file/pom.xml xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/XinQuanFileApplication.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/config/MinioConfig.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/config/ResourcesConfig.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/controller/SysFileController.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/FastDfsSysFileServiceImpl.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/ISysFileService.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/LocalSysFileServiceImpl.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/service/MinioSysFileServiceImpl.java xinquan-modules/xinquan-file/src/main/java/com/xinquan/file/utils/FileUploadUtils.java xinquan-modules/xinquan-file/src/main/resources/banner.txt xinquan-modules/xinquan-file/src/main/resources/logback.xml xinquan-modules/xinquan-gen/pom.xml xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/RuoYiGenApplication.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/config/GenConfig.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/controller/GenController.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/domain/GenTable.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/domain/GenTableColumn.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/mapper/GenTableColumnMapper.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/mapper/GenTableMapper.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/GenTableColumnServiceImpl.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/GenTableServiceImpl.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/IGenTableColumnService.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/service/IGenTableService.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/GenUtils.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/VelocityInitializer.java xinquan-modules/xinquan-gen/src/main/java/com/xinquan/gen/util/VelocityUtils.java xinquan-modules/xinquan-gen/src/main/resources/banner.txt xinquan-modules/xinquan-gen/src/main/resources/logback.xml xinquan-modules/xinquan-gen/src/main/resources/mapper/generator/GenTableColumnMapper.xml xinquan-modules/xinquan-gen/src/main/resources/mapper/generator/GenTableMapper.xml xinquan-modules/xinquan-gen/src/main/resources/vm/java/controller.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/java/domain.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/java/mapper.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/java/service.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/java/serviceImpl.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/java/sub-domain.java.vm xinquan-modules/xinquan-gen/src/main/resources/vm/js/api.js.vm xinquan-modules/xinquan-gen/src/main/resources/vm/sql/sql.vm xinquan-modules/xinquan-gen/src/main/resources/vm/vue/index-tree.vue.vm xinquan-modules/xinquan-gen/src/main/resources/vm/vue/index.vue.vm xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/index-tree.vue.vm xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/index.vue.vm xinquan-modules/xinquan-gen/src/main/resources/vm/vue/v3/readme.txt xinquan-modules/xinquan-gen/src/main/resources/vm/xml/mapper.xml.vm xinquan-modules/xinquan-job/pom.xml xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/RuoYiJobApplication.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/config/ScheduleConfig.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/controller/SysJobController.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/controller/SysJobLogController.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/domain/SysJob.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/domain/SysJobLog.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/mapper/SysJobLogMapper.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/mapper/SysJobMapper.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/ISysJobLogService.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/ISysJobService.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/SysJobLogServiceImpl.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/service/SysJobServiceImpl.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/task/RyTask.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/AbstractQuartzJob.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/CronUtils.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/JobInvokeUtil.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/QuartzDisallowConcurrentExecution.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/QuartzJobExecution.java xinquan-modules/xinquan-job/src/main/java/com/xinquan/job/util/ScheduleUtils.java xinquan-modules/xinquan-job/src/main/resources/banner.txt xinquan-modules/xinquan-job/src/main/resources/logback.xml xinquan-modules/xinquan-job/src/main/resources/mapper/job/SysJobLogMapper.xml xinquan-modules/xinquan-job/src/main/resources/mapper/job/SysJobMapper.xml xinquan-modules/xinquan-meditation/pom.xml xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/XinQuanMeditationApplication.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationCategoryController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationEverydayController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationHallController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationMusicController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationQuestionController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationTagController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/client/ClientMeditationUserOperationController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtClientMeditationUserOperationController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationCategoryController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationEverydayController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationHallController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationMusicController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationQuestionController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/controller/management/MgtMeditationTagController.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/Meditation.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationCategory.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationEveryday.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationHall.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationMusic.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationQuestion.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationTag.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/domain/MeditationUserOperation.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationCategoryMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationEverydayMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationHallMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationMusicMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationQuestionMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationTagMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/mapper/MeditationUserOperationMapper.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationCategoryService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationEverydayService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationHallService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationMusicService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationQuestionService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationTagService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/MeditationUserOperationService.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationCategoryServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationEverydayServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationHallServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationMusicServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationQuestionServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationTagServiceImpl.java xinquan-modules/xinquan-meditation/src/main/java/com/xinquan/meditation/service/impl/MeditationUserOperationServiceImpl.java xinquan-modules/xinquan-meditation/src/main/resources/banner.txt xinquan-modules/xinquan-meditation/src/main/resources/logback.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationCategoryMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationEverydayMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationHallMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationMusicMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationQuestionMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationTagMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mapper/meditation/MeditationUserOperationMapper.xml xinquan-modules/xinquan-meditation/src/main/resources/mybatis-config.xml xinquan-modules/xinquan-order/pom.xml xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/XinQuanOrderApplication.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderController.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/client/ClientOrderPaymentRecordController.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderController.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/controller/management/MgtOrderPaymentRecordController.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/Order.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/domain/OrderPaymentRecord.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderMapper.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/mapper/OrderPaymentRecordMapper.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderPaymentRecordService.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/OrderService.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderPaymentRecordServiceImpl.java xinquan-modules/xinquan-order/src/main/java/com/xinquan/order/service/impl/OrderServiceImpl.java xinquan-modules/xinquan-order/src/main/resources/banner.txt xinquan-modules/xinquan-order/src/main/resources/logback.xml xinquan-modules/xinquan-order/src/main/resources/mybatis-config.xml xinquan-modules/xinquan-system/pom.xml xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/XinQuanSystemApplication.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/BannerController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CommonQuestionController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/ContentSettingController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/CustomConfigController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HomeBackgroundMusicController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/HotWordsController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysConfigController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDeptController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDictDataController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysDictTypeController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysLogininforController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysMenuController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysNoticeController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysOperlogController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysPostController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysProfileController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysRoleController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserOnlineController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/SysUserRoleController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/TreeLevelSettingController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/UserLevelSettingController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VersionController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/controller/VipSettingController.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Banner.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CommonQuestion.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/ContentSetting.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/CustomConfig.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HomeBackgroundMusic.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/HotWords.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysConfig.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysMenu.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysMenus.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysNotice.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysPost.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysRoleDept.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysRoleMenu.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserOnline.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserPost.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/SysUserRole.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/TreeLevelSetting.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/UserLevelSetting.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/Version.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/VipSetting.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/dto/RoleAddDto.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/dto/RoleUpdateDto.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/MetaVo.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/RoleInfoVo.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/RouterVo.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/domain/vo/TreeSelect.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/BannerMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CommonQuestionMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/ContentSettingMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/CustomConfigMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/HomeBackgroundMusicMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/HotWordsMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysConfigMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDeptMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDictDataMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysDictTypeMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysLogininforMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysMenuMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysNoticeMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysOperLogMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysPostMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleDeptMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysRoleMenuMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserPostMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/SysUserRoleMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/TreeLevelSettingMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/UserLevelSettingMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/VersionMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/mapper/VipSettingMapper.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/query/SysOperLogQuery.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysConfigService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDeptService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDictDataService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysDictTypeService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysLogininforService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysMenuService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysNoticeService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysOperLogService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysPermissionService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysPostService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysRoleService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserOnlineService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserRoleService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/ISysUserService.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysConfigServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDeptServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDictDataServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysDictTypeServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysLogininforServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysMenuServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysNoticeServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysOperLogServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysPermissionServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysPostServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysRoleServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserOnlineServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserRoleServiceImpl.java xinquan-modules/xinquan-system/src/main/java/com/xinquan/system/service/impl/SysUserServiceImpl.java xinquan-modules/xinquan-system/src/main/resources/banner.txt xinquan-modules/xinquan-system/src/main/resources/logback.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/BannerMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/CommonQuestionMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/ContentSettingMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/CustomConfigMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/HomeBackgroundMusicMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/HotWordsMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysConfigMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDeptMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDictDataMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysDictTypeMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysLogininforMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysMenuMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysNoticeMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysOperLogMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysPostMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserPostMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/SysUserRoleMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/TreeLevelSettingMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/UserLevelSettingMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/VersionMapper.xml xinquan-modules/xinquan-system/src/main/resources/mapper/system/VipSettingMapper.xml xinquan-modules/xinquan-system/src/main/resources/mybatis-config.xml xinquan-modules/xinquan-user/pom.xml xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/XinQuanUserApplication.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserBankController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserCourseController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserEnergyRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserMeditationController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTagController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserTreeController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWalletRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientAppUserWithdrawController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientPrizeRedemptionRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/client/ClientTagController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/inner/InnerAppUserController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserBankController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserCourseController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserEnergyRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserMeditationController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTagController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserTreeController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWalletRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtAppUserWithdrawController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtPrizeRedemptionRecordController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/controller/management/MgtTagController.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserBank.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserCourse.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserEnergyRecord.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserMeditation.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTag.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserTree.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserWalletRecord.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/AppUserWithdraw.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Prize.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/PrizeRedemptionRecord.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/domain/Tag.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserBankMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserCourseMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserEnergyRecordMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserMeditationMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserTagMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserTreeMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserWalletRecordMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/AppUserWithdrawMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/PrizeMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/PrizeRedemptionRecordMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/mapper/TagMapper.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserBankService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserCourseService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserEnergyRecordService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserMeditationService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserTagService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserTreeService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserWalletRecordService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/AppUserWithdrawService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/PrizeRedemptionRecordService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/PrizeService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/TagService.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserBankServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserCourseServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserEnergyRecordServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserMeditationServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserTagServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserTreeServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserWalletRecordServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/AppUserWithdrawServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/PrizeRedemptionRecordServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/PrizeServiceImpl.java xinquan-modules/xinquan-user/src/main/java/com/xinquan/user/service/impl/TagServiceImpl.java xinquan-modules/xinquan-user/src/main/resources/banner.txt xinquan-modules/xinquan-user/src/main/resources/logback.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserBankMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserCourseMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserEnergyRecordMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserMeditationMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTagMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserTreeMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserWalletRecordMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/AppUserWithdrawMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/PrizeMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/PrizeRedemptionRecordMapper.xml xinquan-modules/xinquan-user/src/main/resources/mapper/user/TagMapper.xml xinquan-modules/xinquan-user/src/main/resources/mybatis-config.xml xinquan-ui/.editorconfig xinquan-ui/.env.development xinquan-ui/.env.production xinquan-ui/.env.staging xinquan-ui/.eslintignore xinquan-ui/.eslintrc.js xinquan-ui/.gitignore xinquan-ui/README.md xinquan-ui/babel.config.js xinquan-ui/bin/build.bat xinquan-ui/bin/package.bat xinquan-ui/bin/run-web.bat xinquan-ui/build/index.js xinquan-ui/package.json xinquan-ui/public/favicon.ico xinquan-ui/public/html/ie.html xinquan-ui/public/index.html xinquan-ui/public/robots.txt xinquan-ui/src/App.vue xinquan-ui/src/api/login.js xinquan-ui/src/api/menu.js xinquan-ui/src/api/monitor/job.js xinquan-ui/src/api/monitor/jobLog.js xinquan-ui/src/api/monitor/online.js xinquan-ui/src/api/system/config.js xinquan-ui/src/api/system/dept.js xinquan-ui/src/api/system/dict/data.js xinquan-ui/src/api/system/dict/type.js xinquan-ui/src/api/system/logininfor.js xinquan-ui/src/api/system/menu.js xinquan-ui/src/api/system/notice.js xinquan-ui/src/api/system/operlog.js xinquan-ui/src/api/system/post.js xinquan-ui/src/api/system/role.js xinquan-ui/src/api/system/user.js xinquan-ui/src/api/tool/gen.js xinquan-ui/src/assets/401_images/401.gif xinquan-ui/src/assets/404_images/404.png xinquan-ui/src/assets/404_images/404_cloud.png xinquan-ui/src/assets/icons/index.js xinquan-ui/src/assets/icons/svg/404.svg xinquan-ui/src/assets/icons/svg/bug.svg xinquan-ui/src/assets/icons/svg/build.svg xinquan-ui/src/assets/icons/svg/button.svg xinquan-ui/src/assets/icons/svg/cascader.svg xinquan-ui/src/assets/icons/svg/chart.svg xinquan-ui/src/assets/icons/svg/checkbox.svg xinquan-ui/src/assets/icons/svg/client.svg xinquan-ui/src/assets/icons/svg/clipboard.svg xinquan-ui/src/assets/icons/svg/code.svg xinquan-ui/src/assets/icons/svg/color.svg xinquan-ui/src/assets/icons/svg/component.svg xinquan-ui/src/assets/icons/svg/dashboard.svg xinquan-ui/src/assets/icons/svg/date-range.svg xinquan-ui/src/assets/icons/svg/date.svg xinquan-ui/src/assets/icons/svg/dict.svg xinquan-ui/src/assets/icons/svg/documentation.svg xinquan-ui/src/assets/icons/svg/download.svg xinquan-ui/src/assets/icons/svg/drag.svg xinquan-ui/src/assets/icons/svg/druid.svg xinquan-ui/src/assets/icons/svg/edit.svg xinquan-ui/src/assets/icons/svg/education.svg xinquan-ui/src/assets/icons/svg/email.svg xinquan-ui/src/assets/icons/svg/example.svg xinquan-ui/src/assets/icons/svg/excel.svg xinquan-ui/src/assets/icons/svg/exit-fullscreen.svg xinquan-ui/src/assets/icons/svg/eye-open.svg xinquan-ui/src/assets/icons/svg/eye.svg xinquan-ui/src/assets/icons/svg/form.svg xinquan-ui/src/assets/icons/svg/fullscreen.svg xinquan-ui/src/assets/icons/svg/github.svg xinquan-ui/src/assets/icons/svg/guide.svg xinquan-ui/src/assets/icons/svg/icon.svg xinquan-ui/src/assets/icons/svg/input.svg xinquan-ui/src/assets/icons/svg/international.svg xinquan-ui/src/assets/icons/svg/job.svg xinquan-ui/src/assets/icons/svg/language.svg xinquan-ui/src/assets/icons/svg/link.svg xinquan-ui/src/assets/icons/svg/list.svg xinquan-ui/src/assets/icons/svg/lock.svg xinquan-ui/src/assets/icons/svg/log.svg xinquan-ui/src/assets/icons/svg/logininfor.svg xinquan-ui/src/assets/icons/svg/message.svg xinquan-ui/src/assets/icons/svg/money.svg xinquan-ui/src/assets/icons/svg/monitor.svg xinquan-ui/src/assets/icons/svg/nacos.svg xinquan-ui/src/assets/icons/svg/nested.svg xinquan-ui/src/assets/icons/svg/number.svg xinquan-ui/src/assets/icons/svg/online.svg xinquan-ui/src/assets/icons/svg/password.svg xinquan-ui/src/assets/icons/svg/pdf.svg xinquan-ui/src/assets/icons/svg/people.svg xinquan-ui/src/assets/icons/svg/peoples.svg xinquan-ui/src/assets/icons/svg/phone.svg xinquan-ui/src/assets/icons/svg/post.svg xinquan-ui/src/assets/icons/svg/qq.svg xinquan-ui/src/assets/icons/svg/question.svg xinquan-ui/src/assets/icons/svg/radio.svg xinquan-ui/src/assets/icons/svg/rate.svg xinquan-ui/src/assets/icons/svg/row.svg xinquan-ui/src/assets/icons/svg/search.svg xinquan-ui/src/assets/icons/svg/select.svg xinquan-ui/src/assets/icons/svg/sentinel.svg xinquan-ui/src/assets/icons/svg/server.svg xinquan-ui/src/assets/icons/svg/shopping.svg xinquan-ui/src/assets/icons/svg/size.svg xinquan-ui/src/assets/icons/svg/skill.svg xinquan-ui/src/assets/icons/svg/slider.svg xinquan-ui/src/assets/icons/svg/star.svg xinquan-ui/src/assets/icons/svg/swagger.svg xinquan-ui/src/assets/icons/svg/switch.svg xinquan-ui/src/assets/icons/svg/system.svg xinquan-ui/src/assets/icons/svg/tab.svg xinquan-ui/src/assets/icons/svg/table.svg xinquan-ui/src/assets/icons/svg/textarea.svg xinquan-ui/src/assets/icons/svg/theme.svg xinquan-ui/src/assets/icons/svg/time-range.svg xinquan-ui/src/assets/icons/svg/time.svg xinquan-ui/src/assets/icons/svg/tool.svg xinquan-ui/src/assets/icons/svg/tree-table.svg xinquan-ui/src/assets/icons/svg/tree.svg xinquan-ui/src/assets/icons/svg/upload.svg xinquan-ui/src/assets/icons/svg/user.svg xinquan-ui/src/assets/icons/svg/validCode.svg xinquan-ui/src/assets/icons/svg/wechat.svg xinquan-ui/src/assets/icons/svg/zip.svg xinquan-ui/src/assets/images/dark.svg xinquan-ui/src/assets/images/light.svg xinquan-ui/src/assets/images/login-background.jpg xinquan-ui/src/assets/images/profile.jpg xinquan-ui/src/assets/logo/logo.png xinquan-ui/src/assets/styles/btn.scss xinquan-ui/src/assets/styles/element-ui.scss xinquan-ui/src/assets/styles/element-variables.scss xinquan-ui/src/assets/styles/index.scss xinquan-ui/src/assets/styles/mixin.scss xinquan-ui/src/assets/styles/ruoyi.scss xinquan-ui/src/assets/styles/sidebar.scss xinquan-ui/src/assets/styles/transition.scss xinquan-ui/src/assets/styles/variables.scss xinquan-ui/src/components/Breadcrumb/index.vue xinquan-ui/src/components/Crontab/day.vue xinquan-ui/src/components/Crontab/hour.vue xinquan-ui/src/components/Crontab/index.vue xinquan-ui/src/components/Crontab/min.vue xinquan-ui/src/components/Crontab/month.vue xinquan-ui/src/components/Crontab/result.vue xinquan-ui/src/components/Crontab/second.vue xinquan-ui/src/components/Crontab/week.vue xinquan-ui/src/components/Crontab/year.vue xinquan-ui/src/components/DictData/index.js xinquan-ui/src/components/DictTag/index.vue xinquan-ui/src/components/Editor/index.vue xinquan-ui/src/components/FileUpload/index.vue xinquan-ui/src/components/Hamburger/index.vue xinquan-ui/src/components/HeaderSearch/index.vue xinquan-ui/src/components/IconSelect/index.vue xinquan-ui/src/components/IconSelect/requireIcons.js xinquan-ui/src/components/ImagePreview/index.vue xinquan-ui/src/components/ImageUpload/index.vue xinquan-ui/src/components/Pagination/index.vue xinquan-ui/src/components/PanThumb/index.vue xinquan-ui/src/components/ParentView/index.vue xinquan-ui/src/components/RightPanel/index.vue xinquan-ui/src/components/RightToolbar/index.vue xinquan-ui/src/components/RuoYi/Doc/index.vue xinquan-ui/src/components/RuoYi/Git/index.vue xinquan-ui/src/components/Screenfull/index.vue xinquan-ui/src/components/SizeSelect/index.vue xinquan-ui/src/components/SvgIcon/index.vue xinquan-ui/src/components/ThemePicker/index.vue xinquan-ui/src/components/TopNav/index.vue xinquan-ui/src/components/iFrame/index.vue xinquan-ui/src/directive/dialog/drag.js xinquan-ui/src/directive/dialog/dragHeight.js xinquan-ui/src/directive/dialog/dragWidth.js xinquan-ui/src/directive/index.js xinquan-ui/src/directive/module/clipboard.js xinquan-ui/src/directive/permission/hasPermi.js xinquan-ui/src/directive/permission/hasRole.js xinquan-ui/src/layout/components/AppMain.vue xinquan-ui/src/layout/components/IframeToggle/index.vue xinquan-ui/src/layout/components/InnerLink/index.vue xinquan-ui/src/layout/components/Navbar.vue xinquan-ui/src/layout/components/Settings/index.vue xinquan-ui/src/layout/components/Sidebar/FixiOSBug.js xinquan-ui/src/layout/components/Sidebar/Item.vue xinquan-ui/src/layout/components/Sidebar/Link.vue xinquan-ui/src/layout/components/Sidebar/Logo.vue xinquan-ui/src/layout/components/Sidebar/SidebarItem.vue xinquan-ui/src/layout/components/Sidebar/index.vue xinquan-ui/src/layout/components/TagsView/ScrollPane.vue xinquan-ui/src/layout/components/TagsView/index.vue xinquan-ui/src/layout/components/index.js xinquan-ui/src/layout/index.vue xinquan-ui/src/layout/mixin/ResizeHandler.js xinquan-ui/src/main.js xinquan-ui/src/permission.js xinquan-ui/src/plugins/auth.js xinquan-ui/src/plugins/cache.js xinquan-ui/src/plugins/download.js xinquan-ui/src/plugins/index.js xinquan-ui/src/plugins/modal.js xinquan-ui/src/plugins/tab.js xinquan-ui/src/router/index.js xinquan-ui/src/settings.js xinquan-ui/src/store/getters.js xinquan-ui/src/store/index.js xinquan-ui/src/store/modules/app.js xinquan-ui/src/store/modules/dict.js xinquan-ui/src/store/modules/permission.js xinquan-ui/src/store/modules/settings.js xinquan-ui/src/store/modules/tagsView.js xinquan-ui/src/store/modules/user.js xinquan-ui/src/utils/auth.js xinquan-ui/src/utils/dict/Dict.js xinquan-ui/src/utils/dict/DictConverter.js xinquan-ui/src/utils/dict/DictData.js xinquan-ui/src/utils/dict/DictMeta.js xinquan-ui/src/utils/dict/DictOptions.js xinquan-ui/src/utils/dict/index.js xinquan-ui/src/utils/errorCode.js xinquan-ui/src/utils/generator/config.js xinquan-ui/src/utils/generator/css.js xinquan-ui/src/utils/generator/drawingDefault.js xinquan-ui/src/utils/generator/html.js xinquan-ui/src/utils/generator/icon.json xinquan-ui/src/utils/generator/js.js xinquan-ui/src/utils/generator/render.js xinquan-ui/src/utils/index.js xinquan-ui/src/utils/jsencrypt.js xinquan-ui/src/utils/permission.js xinquan-ui/src/utils/request.js xinquan-ui/src/utils/ruoyi.js xinquan-ui/src/utils/scroll-to.js xinquan-ui/src/utils/validate.js xinquan-ui/src/views/components/icons/element-icons.js xinquan-ui/src/views/components/icons/index.vue xinquan-ui/src/views/components/icons/svg-icons.js xinquan-ui/src/views/dashboard/BarChart.vue xinquan-ui/src/views/dashboard/LineChart.vue xinquan-ui/src/views/dashboard/PanelGroup.vue xinquan-ui/src/views/dashboard/PieChart.vue xinquan-ui/src/views/dashboard/RaddarChart.vue xinquan-ui/src/views/dashboard/mixins/resize.js xinquan-ui/src/views/error/401.vue xinquan-ui/src/views/error/404.vue xinquan-ui/src/views/index.vue xinquan-ui/src/views/index_v1.vue xinquan-ui/src/views/login.vue xinquan-ui/src/views/monitor/job/index.vue xinquan-ui/src/views/monitor/job/log.vue xinquan-ui/src/views/monitor/online/index.vue xinquan-ui/src/views/redirect.vue xinquan-ui/src/views/register.vue xinquan-ui/src/views/system/config/index.vue xinquan-ui/src/views/system/dept/index.vue xinquan-ui/src/views/system/dict/data.vue xinquan-ui/src/views/system/dict/index.vue xinquan-ui/src/views/system/logininfor/index.vue xinquan-ui/src/views/system/menu/index.vue xinquan-ui/src/views/system/notice/index.vue xinquan-ui/src/views/system/operlog/index.vue xinquan-ui/src/views/system/post/index.vue xinquan-ui/src/views/system/role/authUser.vue xinquan-ui/src/views/system/role/index.vue xinquan-ui/src/views/system/role/selectUser.vue xinquan-ui/src/views/system/user/authRole.vue xinquan-ui/src/views/system/user/index.vue xinquan-ui/src/views/system/user/profile/index.vue xinquan-ui/src/views/system/user/profile/resetPwd.vue xinquan-ui/src/views/system/user/profile/userAvatar.vue xinquan-ui/src/views/system/user/profile/userInfo.vue xinquan-ui/src/views/tool/build/CodeTypeDialog.vue xinquan-ui/src/views/tool/build/DraggableItem.vue xinquan-ui/src/views/tool/build/IconsDialog.vue xinquan-ui/src/views/tool/build/RightPanel.vue xinquan-ui/src/views/tool/build/TreeNodeDialog.vue xinquan-ui/src/views/tool/build/index.vue xinquan-ui/src/views/tool/gen/basicInfoForm.vue xinquan-ui/src/views/tool/gen/editTable.vue xinquan-ui/src/views/tool/gen/genInfoForm.vue xinquan-ui/src/views/tool/gen/importTable.vue xinquan-ui/src/views/tool/gen/index.vue xinquan-ui/vue.config.js xinquan-visual/pom.xml xinquan-visual/xinquan-monitor/pom.xml xinquan-visual/xinquan-monitor/src/main/java/com/xinquan/modules/monitor/RuoYiMonitorApplication.java xinquan-visual/xinquan-monitor/src/main/java/com/xinquan/modules/monitor/config/WebSecurityConfigurer.java xinquan-visual/xinquan-monitor/src/main/resources/banner.txt xinquan-visual/xinquan-monitor/src/main/resources/logback.xml