d0a8aa889e60f32964bbb0ce2facadd917c3599f..0bf868d3cdf9226e178c076d3b588ed5207409a0
2023-11-24 kongzy
merge
0bf868 对比 | 目录
2023-11-24 kongzy
new project
ebe94e 对比 | 目录
已修改1个文件
已添加140个文件
10014 ■■■■■ 文件已修改
.gitignore 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/pom.xml 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/GkhyAdminApplication.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/config/FlywayConfig.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysAgencyController.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysCommonController.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysDictDataController.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysDictTypeController.java 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysLawController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysLoginController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysNoticeController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysRegionController.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysUserController.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/application-dev.yml 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/application.yml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123001_add_user.sql 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123002_dict_type.sql 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123003_dict_data.sql 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123004_config.sql 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123005_agency.sql 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123006_notice.sql 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231123007_law.sql 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231124001_region.sql 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/db/migration/V20231124002_attach.sql 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/main/resources/logback-spring.xml 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-admin/src/test/java/com/gkhy/admin/MybatisPlusGenerator.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/pom.xml 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/annotation/DataScope.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/annotation/DataSource.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/annotation/RepeatSubmit.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/api/CommonPage.java 88 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/api/CommonResult.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/api/IErrorCode.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/api/ResultCode.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/BaseFlywayConfig.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/BaseRedisConfig.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/BaseSwaggerConfig.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/CaffeineConfig.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/DynamicDataSourceContextHolder.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/MybatisPlusConfig.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/config/ThreadPoolConfig.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/BaseEntity.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/PageDomain.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/TableSupport.java 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/WebLog.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/vo/AccountVO.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/ApproveStatusEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/DataSourceTypeEnum.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/DeleteFlagEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/SocialSameEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/UserIdentityEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/UserSexEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/UserStatusEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/enums/UserTypeEnum.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/exception/ApiException.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/exception/UtilException.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/service/RedisService.java 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/service/impl/RedisServiceImpl.java 197 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/BeanValidators.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/CommonUtil.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/ConvertUtil.java 990 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/JwtTokenUtil.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/PageUtil.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/RedisUtils.java 780 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/RequestUtil.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/ServletUtil.java 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/SpringContextUtils.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/SqlUtil.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/utils/Threads.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/validate/AgencyGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-common/src/main/java/com/gkhy/assess/common/validate/ExpertGroup.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/ApplicationConfig.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/DynamicDataSource.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/MyWebMvcConfig.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/RedisConfig.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/config/properties/DruidProperties.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/exception/GlobalExceptionHandler.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/JwtToken.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/filter/JwtFilter.java 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/realm/UserRealm.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysPasswordService.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/pom.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysAgency.java 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysAttach.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysConfig.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysDictData.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysDictType.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysLaw.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysNotice.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysRegion.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/SysUser.java 169 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/domain/vo/UploadObjectVO.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysAgencyMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysAttachMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysConfigMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysDictDataMapper.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysDictTypeMapper.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysLawMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysNoticeMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysRegionMapper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysUserMapper.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysAgencyService.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysAttachService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysCommonService.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysConfigService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysDictDataService.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysDictTypeService.java 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysLawService.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysNoticeService.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysRegionService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/SysUserService.java 179 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysAgencyServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysAttachServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysCommonServiceImpl.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysConfigServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysDictDataServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysDictTypeServiceImpl.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysLawServiceImpl.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysNoticeServiceImpl.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysRegionServiceImpl.java 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java 374 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysAgencyMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysAttachMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysConfigMapper.xml 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysDictDataMapper.xml 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysDictTypeMapper.xml 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysLawMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysNoticeMapper.xml 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysRegionMapper.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/main/resources/mapper/system/SysUserMapper.xml 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/test/java/com/gkhy/system/DemoTest.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
assess-system/src/test/java/com/gkhy/system/MybatisPlusGenerator.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 190 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.gitignore
@@ -1,3 +1,38 @@
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
logs/
upload/
*.class
# Mobile Tools for Java (J2ME)
assess-admin/pom.xml
对比新文件
@@ -0,0 +1,27 @@
<?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.gkhy.assess</groupId>
        <artifactId>smart_assess</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>assess-admin</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>
        <dependency>
            <groupId>com.gkhy.assess</groupId>
            <artifactId>assess-framework</artifactId>
        </dependency>
    </dependencies>
</project>
assess-admin/src/main/java/com/gkhy/assess/admin/GkhyAdminApplication.java
对比新文件
@@ -0,0 +1,15 @@
package com.gkhy.assess.admin;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
@ComponentScan("com.gkhy.assess")
public class GkhyAdminApplication {
    public static void main(String[] args) {
        SpringApplication.run(GkhyAdminApplication.class,args);
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/config/FlywayConfig.java
对比新文件
@@ -0,0 +1,24 @@
package com.gkhy.assess.admin.config;
import com.gkhy.assess.common.config.BaseFlywayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import javax.annotation.PostConstruct;
@Configuration
@DependsOn({"druidConfig"})
public class FlywayConfig extends BaseFlywayConfig {
    @Autowired
    private ApplicationContext applicationContext;
    @PostConstruct
    public void migrate() {
        initDataSource("masterDataSource");
        if(applicationContext.containsBean("slaveDataSource")){
            initDataSource("slaveDataSource");
        }
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysAgencyController.java
对比新文件
@@ -0,0 +1,47 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysAgency;
import com.gkhy.assess.system.service.SysAgencyService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Api(tags = "机构前端控制器")
@RestController
@RequestMapping("/system/agency")
public class SysAgencyController {
    @Autowired
    private SysAgencyService agencyService;
    @ApiOperation(value = "机构列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/agencyList")
    public CommonResult agencyList(SysAgency agency){
        return CommonResult.success(agencyService.agencyList(agency));
    }
    @ApiOperation(value = "根据id获取机构详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "agencyId", dataType = "int", required = true, value = "机构id")
    })
    @GetMapping("/getAgencyById")
    public CommonResult getAgencyById(@RequestParam(required = true) Long agencyId){
        return CommonResult.success(agencyService.getAgencyById(agencyId));
    }
    @ApiOperation(value = "校验机构名称")
    @PostMapping("/checkAgencyNameUnique")
    public boolean checkAgencyNameUnique(SysAgency agency)
    {
        return agencyService.checkAgencyNameUnique(agency);
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysCommonController.java
对比新文件
@@ -0,0 +1,30 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysAgency;
import com.gkhy.assess.system.domain.vo.UploadObjectVO;
import com.gkhy.assess.system.service.SysAgencyService;
import com.gkhy.assess.system.service.SysCommonService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
@Api(tags = "通用接口前端控制器")
@RestController
@RequestMapping("/system/common")
public class SysCommonController {
    @Autowired
    private SysCommonService commonService;
    @ApiOperation(value = "上传头像")
    @PostMapping("/uploadIcon")
    public CommonResult<UploadObjectVO> uploadIcon(MultipartFile file){
        return CommonResult.success(commonService.uploadFile(file));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysDictDataController.java
对比新文件
@@ -0,0 +1,72 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysDictData;
import com.gkhy.assess.system.domain.SysDictType;
import com.gkhy.assess.system.service.SysDictDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "数据字典数据前端控制器")
@RestController
@RequestMapping("/system/dictData")
public class SysDictDataController {
    @Autowired
    private SysDictDataService dictDataService;
    @ApiOperation(value = "字典数据列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/dictDataList")
    public CommonResult dictDataList(SysDictData dictData){
        return CommonResult.success(dictDataService.dictDataList(dictData));
    }
    @ApiOperation(value = "根据id获取字典数据详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "dictId", dataType = "int", required = true, value = "字典类型id")
    })
    @GetMapping("/getDictDataById")
    public CommonResult getDictDataById(@RequestParam(required = true)Long dictId){
        return CommonResult.success(dictDataService.getDictDataById(dictId));
    }
    @ApiOperation(value = "新增字典数据")
    @PostMapping("/addDictData")
    public CommonResult addDictData(@Validated @RequestBody SysDictData dictData){
        return CommonResult.success(dictDataService.addDictData(dictData));
    }
    @ApiOperation(value = "编辑字典数据")
    @PutMapping("/editDictData")
    public CommonResult editDictData(@Validated @RequestBody SysDictData dictData){
        return CommonResult.success(dictDataService.editDictData(dictData));
    }
    @ApiOperation(value = "删除字典数据")
    @PutMapping("/remove/{dictId}")
    public CommonResult removeDictData(@PathVariable(name = "dictId")Long dictId){
        return CommonResult.success(dictDataService.deleteDictDataById(dictId));
    }
    @ApiOperation(value = "字典数据状态修改,停用/启用")
    @PostMapping("/changeStatus")
    public CommonResult changeStatus(SysDictData SysDictData)
    {
        return CommonResult.success(dictDataService.changeDictDataStatus(SysDictData));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysDictTypeController.java
对比新文件
@@ -0,0 +1,93 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysDictType;
import com.gkhy.assess.system.domain.SysLaw;
import com.gkhy.assess.system.service.SysDictTypeService;
import com.gkhy.assess.system.service.SysLawService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "数据字典类型前端控制器")
@RestController
@RequestMapping("/system/dictType")
public class SysDictTypeController {
    @Autowired
    private SysDictTypeService dictTypeService;
    @ApiOperation(value = "字典类型列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/dictTypeList")
    public CommonResult dictTypeList(SysDictType dictType){
        return CommonResult.success(dictTypeService.dictTypeList(dictType));
    }
    @ApiOperation(value = "根据id获取字典类型详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "dictId", dataType = "int", required = true, value = "字典类型id")
    })
    @GetMapping("/getDictTypeById")
    public CommonResult getDictTypeById(@RequestParam(required = true)Long dictId){
        return CommonResult.success(dictTypeService.getDictTypeById(dictId));
    }
    @ApiOperation(value = "根据类型获取字典数据")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "dictType", dataType = "int", required = true, value = "类型")
    })
    @GetMapping("/getDictDataByType")
    public CommonResult getDictDataByType(@RequestParam(required = true)String dictType){
        return CommonResult.success(dictTypeService.getDictDataByType(dictType));
    }
    @ApiOperation(value = "新增字典类型")
    @PostMapping("/addDictType")
    public CommonResult addDictType(@Validated @RequestBody SysDictType dictType){
        return CommonResult.success(dictTypeService.addDictType(dictType));
    }
    @ApiOperation(value = "编辑字典类型")
    @PutMapping("/editDictType")
    public CommonResult editDictType(@Validated @RequestBody SysDictType dictType){
        return CommonResult.success(dictTypeService.editDictType(dictType));
    }
    @ApiOperation(value = "删除字典类型")
    @DeleteMapping("/remove/{dictId}")
    public CommonResult removeDictType(@PathVariable(name = "dictId")Long dictId){
        return CommonResult.success(dictTypeService.deleteDictTypeById(dictId));
    }
    @ApiOperation(value = "字典类型状态修改,停用/启用")
    @PostMapping("/changeStatus")
    public CommonResult changeStatus(SysDictType SysDictType)
    {
        return CommonResult.success(dictTypeService.changeDictTypeStatus(SysDictType));
    }
    /**
     * 校验字典类型
     */
    @PostMapping("/checkDictTypeUnique")
    public CommonResult checkDictTypeUnique(SysDictType dictType)
    {
        return CommonResult.success(dictTypeService.checkDictTypeUnique(dictType));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysLawController.java
对比新文件
@@ -0,0 +1,69 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysLaw;
import com.gkhy.assess.system.service.SysLawService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "法律法规前端控制器")
@RestController
@RequestMapping("/system/law")
public class SysLawController {
    @Autowired
    private SysLawService lawService;
    @ApiOperation(value = "法律法规列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/lawList")
    public CommonResult lawList(SysLaw law){
        return CommonResult.success(lawService.lawList(law));
    }
    @ApiOperation(value = "根据id获取法律法规详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "lawId", dataType = "int", required = true, value = "法律法规id")
    })
    @GetMapping("/getLawById")
    public CommonResult getLawById(@RequestParam(required = true)Long lawId){
        return CommonResult.success(lawService.getLawById(lawId));
    }
    @ApiOperation(value = "新增法律法规")
    @PostMapping("/addLaw")
    public CommonResult addLaw(@Validated @RequestBody SysLaw law){
        return CommonResult.success(lawService.addLaw(law));
    }
    @ApiOperation(value = "编辑法律法规")
    @PutMapping("/editLaw")
    public CommonResult editLaw(@Validated @RequestBody SysLaw law){
        return CommonResult.success(lawService.editLaw(law));
    }
    @ApiOperation(value = "删除法律法规")
    @PutMapping("/remove/{lawId}")
    public CommonResult removeLaw(@PathVariable(name = "lawId")Long lawId){
        return CommonResult.success(lawService.deleteLawById(lawId));
    }
    @ApiOperation(value = "法律法规状态修改,停用/启用")
    @PostMapping("/changeStatus")
    public CommonResult changeStatus(SysLaw law)
    {
        return CommonResult.success(lawService.changeLawStatus(law));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysLoginController.java
对比新文件
@@ -0,0 +1,39 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.common.domain.vo.LoginBody;
import com.gkhy.assess.system.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author kzy
 * @since 2023-10-17 14:26:29
 */
@RestController
@RequestMapping("/account")
public class SysLoginController {
    @Autowired
    private SysUserService sysUserService;
    @PostMapping("/login")
    public CommonResult login(@RequestBody LoginBody loginBody){
        return CommonResult.success(sysUserService.login(loginBody));
    }
    @PostMapping("/logout")
    public CommonResult logout(){
        sysUserService.logout();
        return CommonResult.success();
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysNoticeController.java
对比新文件
@@ -0,0 +1,69 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysNotice;
import com.gkhy.assess.system.service.SysNoticeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "通知公告前端控制器")
@RestController
@RequestMapping("/system/notice")
public class SysNoticeController {
    @Autowired
    private SysNoticeService noticeService;
    @ApiOperation(value = "通知列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/noticeList")
    public CommonResult noticeList(SysNotice notice){
        return CommonResult.success(noticeService.noticeList(notice));
    }
    @ApiOperation(value = "根据id获取通知详情")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "noticeId", dataType = "int", required = true, value = "通知id")
    })
    @GetMapping("/getNoticeById")
    public CommonResult getNoticeById(@RequestParam(required = true)Long noticeId){
        return CommonResult.success(noticeService.getNoticeById(noticeId));
    }
    @ApiOperation(value = "新增通知")
    @PostMapping("/addNotice")
    public CommonResult addNotice(@Validated @RequestBody SysNotice notice){
        return CommonResult.success(noticeService.addNotice(notice));
    }
    @ApiOperation(value = "编辑通知")
    @PutMapping("/editNotice")
    public CommonResult editNotice(@Validated @RequestBody SysNotice notice){
        return CommonResult.success(noticeService.editNotice(notice));
    }
    @ApiOperation(value = "删除通知")
    @PutMapping("/remove/{noticeId}")
    public CommonResult removeNotice(@PathVariable(name = "noticeId")Long noticeId){
        return CommonResult.success(noticeService.deleteNoticeById(noticeId));
    }
    @ApiOperation(value = "通知状态修改,停用/启用")
    @PostMapping("/changeStatus")
    public CommonResult changeStatus(SysNotice notice)
    {
        return CommonResult.success(noticeService.changeNoticeStatus(notice));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysRegionController.java
对比新文件
@@ -0,0 +1,58 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.system.domain.SysRegion;
import com.gkhy.assess.system.service.SysRegionService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "地区前端控制器")
@RestController
@RequestMapping("/system/region")
public class SysRegionController {
    @Autowired
    private SysRegionService regionService;
    @ApiOperation(value = "地区列表(树形结构)")
    @GetMapping("/regionTree")
    public CommonResult regionTree(SysRegion region){
        return CommonResult.success(regionService.regionTree(region));
    }
    @ApiOperation(value = "根据id获取子地区")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "regionId", dataType = "int", required = true, value = "地区id")
    })
    @GetMapping("/getChildRegionById")
    public CommonResult getChildRegionById(@RequestParam(required = true)Long regionId){
        return CommonResult.success(regionService.getChildRegionById(regionId));
    }
    @ApiOperation(value = "新增地区")
    @PostMapping("/addRegion")
    public CommonResult addLaw(@Validated @RequestBody SysRegion region){
        return CommonResult.success(regionService.addRegion(region));
    }
    @ApiOperation(value = "编辑地区")
    @PutMapping("/editRegion")
    public CommonResult editLaw(@Validated @RequestBody SysRegion region){
        return CommonResult.success(regionService.editRegion(region));
    }
    @ApiOperation(value = "删除地区")
    @PutMapping("/remove/{regionId}")
    public CommonResult removeRegion(@PathVariable(name = "regionId")Long regionId){
        return CommonResult.success(regionService.deleteRegionById(regionId));
    }
}
assess-admin/src/main/java/com/gkhy/assess/admin/controller/SysUserController.java
对比新文件
@@ -0,0 +1,127 @@
package com.gkhy.assess.admin.controller;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.common.validate.AgencyGroup;
import com.gkhy.assess.common.validate.ExpertGroup;
import com.gkhy.assess.system.domain.SysUser;
import com.gkhy.assess.system.service.SysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@Api(tags = "用户前端控制器")
@RestController
@RequestMapping("/system/user")
public class SysUserController {
    @Autowired
    private SysUserService sysUserService;
    @ApiOperation(value = "监管用户列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/monitorList")
    public CommonResult monitorList(SysUser user){
        return CommonResult.success(sysUserService.monitorList(user));
    }
    @ApiOperation(value = "机构用户列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/agencyList")
    public CommonResult agencyList(SysUser user){
        return CommonResult.success(sysUserService.agencyList(user));
    }
    @ApiOperation(value = "专家用户列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(paramType = "query", name = "pageNum", dataType = "int", required = false, value = "当前页,默认1"),
            @ApiImplicitParam(paramType = "query", name = "pageSize", dataType = "int", required = false, value = "每页数目,默认10")
    })
    @GetMapping("/expertList")
    public CommonResult expertList(SysUser user){
        return CommonResult.success(sysUserService.expertList(user));
    }
    @ApiOperation(value = "机构注册")
    @PostMapping("/agencyRegister")
    public CommonResult agencyRegister(@Validated(AgencyGroup.class) @RequestBody SysUser user){
        return CommonResult.success(sysUserService.agencyRegister(user));
    }
    @ApiOperation(value = "创建专家")
    @PostMapping("/addExpert")
    public CommonResult addExpert(@Validated(ExpertGroup.class) @RequestBody SysUser user){
        return CommonResult.success(sysUserService.addExpert(user));
    }
    @ApiOperation(value = "编辑机构")
    @PutMapping("/editAgency")
    public CommonResult editAgency(@Validated(ExpertGroup.class) @RequestBody SysUser user){
        return CommonResult.success(sysUserService.editAgency(user));
    }
    @ApiOperation(value = "编辑专家")
    @PutMapping("/editExpert")
    public CommonResult editExpert(@Validated(ExpertGroup.class) @RequestBody SysUser user){
        return CommonResult.success(sysUserService.editExpert(user));
    }
    @ApiOperation(value = "校验用户名")
    @PostMapping("/checkUserNameUnique")
    public boolean checkLoginNameUnique(SysUser user)
    {
        return sysUserService.checkUsernameUnique(user);
    }
    @ApiOperation(value = "校验手机号")
    @PostMapping("/checkPhoneUnique")
    public boolean checkPhoneUnique(SysUser user)
    {
        return sysUserService.checkPhoneUnique(user);
    }
    /**
     * 用户状态修改
     */
    @ApiOperation(value = "用户状态修改,停用/启用")
    @PostMapping("/changeStatus")
    public CommonResult changeStatus(SysUser user)
    {
        return CommonResult.success(sysUserService.changeUserStatus(user));
    }
    @ApiOperation(value = "审批状态修改,停用/启用")
    @PostMapping("/changeApprove")
    public CommonResult changeApprove(SysUser user)
    {
        return CommonResult.success(sysUserService.changeApprove(user));
    }
    @ApiOperation(value = "根据id删除用户")
    @DeleteMapping("/remove/{userId}")
    public CommonResult removeUser(@PathVariable(name = "userId") Long userId)
    {
        return CommonResult.success(sysUserService.deleteUserById(userId));
    }
}
assess-admin/src/main/resources/application-dev.yml
对比新文件
@@ -0,0 +1,80 @@
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    druid:
      # 主库数据源
      master:
        url: jdbc:mysql://localhost:3306/smart_assess?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=Asia/Shanghai&useSSL=false
        username: root
        password: password
      # 从库数据源
      slave:
        enabled: false
        url:
        username:
        password:
      initialSize: 5 #连接池初始化大小
      minIdle: 10 #最小空闲连接数
      maxActive: 20 #最大连接数
      # 配置获取连接等待超时的时间
      maxWait: 60000
      # 配置连接超时时间
      connectTimeout: 30000
      # 配置网络超时时间
      socketTimeout: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      timeBetweenEvictionRunsMillis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      minEvictableIdleTimeMillis: 300000
      # 配置一个连接在池中最大生存的时间,单位是毫秒
      maxEvictableIdleTimeMillis: 900000
      # 配置检测连接是否有效
      validationQuery: SELECT 1 FROM DUAL
      testWhileIdle: true
      testOnBorrow: false
      testOnReturn: false
      web-stat-filter:
        exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" #不统计这些请求数据
      stat-view-servlet: #访问监控网页的登录用户名和密码
        login-username: druid
        login-password: druid
  #redis 配置
  redis:
    database: 0
    host: 127.0.0.1
    port: 6379
    password:
# mybatis-plus相关配置
mybatis-plus:
  # xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  # 以下配置均有默认值,可以不设置
  global-config:
    db-config:
      #主键类型 AUTO:"数据库ID自增" INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
      id-type: auto
      #字段策略 IGNORED:"忽略判断"  NOT_NULL:"非 NULL 判断")  NOT_EMPTY:"非空判断"
      field-strategy: NOT_EMPTY
      #数据库类型
      db-type: MYSQL
  configuration:
    # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
    map-underscore-to-camel-case: true
    # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
    call-setters-on-nulls: true
    # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
logging:
  level:
    root: INFO
    org:
      com.nms.swspkmas_standalone: DEBUG
swagger:
  enabled: true
assess-admin/src/main/resources/application.yml
对比新文件
@@ -0,0 +1,43 @@
spring:
  application:
    name: assess_admin
  profiles:
    active: dev
  servlet:
    multipart:
      enabled: true
      # 单个文件大小
      max-file-size: 10MB
      # 设置总上传的文件大小
      max-request-size: 20MB
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
server:
  port: 8088
  servlet:
    context-path: /api
#shiro配置
#shiro:
#  sessionManager:
#    sessionIdCookieEnabled: true
#    sessionIdUrlRewritingEnabled: true
#  unauthorizedUrl: /unauthorizedurl
#  web:
#    enabled: true
#  successUrl: /index
#  loginUrl: /account/login
# 用户配置
user:
  password:
    # 密码错误{maxRetryCount}次锁定10分钟
    maxRetryCount: 5
image:
  root_path: upload
  upload_image: upload/images
  upload_file: upload/documents
assess-admin/src/main/resources/db/migration/V20231123001_add_user.sql
对比新文件
@@ -0,0 +1,35 @@
drop table if exists `smart_assess`.`sys_user`;
CREATE TABLE `smart_assess`.`sys_user`  (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`username` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '登录账号',
`name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '用户昵称/姓名',
`identity` tinyint NOT NULL COMMENT '用户身份(0代表监管用户,1代表机构用户,2代表专家用户)',
`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '邮箱',
`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '手机号码',
`sex` tinyint NULL DEFAULT 2 COMMENT '用户性别(0男,1女,2未知,默认2)',
`avatar` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '头像路径',
`password` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密码',
`salt` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '盐加密',
`status` tinyint NULL DEFAULT 0 COMMENT '账号状态(0正常,1停用,默认0)',
`del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标志(0代表存在,1代表删除,默认0)',
`user_type` tinyint NULL DEFAULT 0 COMMENT '账号类型(0代表工作人员,1代表领导,默认0)',
`manage_region` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '管辖地区',
`expert_type` tinyint NULL DEFAULT 0 COMMENT '专家类型(0代表安全评价,1代表检验检测,默认0)',
`agency_id` bigint NULL DEFAULT NULL COMMENT '机构id',
`post` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '职务',
`job_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '职称',
`major` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '专业方向',
`approve` tinyint NULL DEFAULT 1 COMMENT '审批状态(0审批通过,1待审批,2未通过 默认1)',
`login_ip` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '最后登录ip',
`login_date` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '最后登录时间',
`pwd_update_date` datetime NULL DEFAULT NULL COMMENT '密码最后更新时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `index_username`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '用户表' ROW_FORMAT = Dynamic;
insert into sys_user values(1,'admin', '国科鸿宇', 0, 'gkhy@163.com', '15888888888', 0, '', '29c67a30398638269fe600f73a054934', '111111', 0, 0, 0,'',null,null,'','','',1,'127.0.0.1', sysdate(), sysdate(), 'admin', sysdate(), '', sysdate(), '管理员');
assess-admin/src/main/resources/db/migration/V20231123002_dict_type.sql
对比新文件
@@ -0,0 +1,22 @@
-- ----------------------------
-- 字典类型表
-- ----------------------------
drop table if exists `smart_assess`.`sys_dict_type`;
CREATE TABLE `smart_assess`.`sys_dict_type`  (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典名称',
`dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典类型',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常,1停用)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `index_name`(`name`) USING BTREE,
UNIQUE INDEX `index_type`(`dict_type`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典类型表' ROW_FORMAT = Dynamic;
insert into sys_dict_type values(1,  '评价类型', 'sys_assess_type', 0, 'admin', sysdate(), '', sysdate(), '评价类型列表');
insert into sys_dict_type values(2,  '业务范围', 'sys_business_scope', 0, 'admin', sysdate(), '', sysdate(), '业务范围列表');
assess-admin/src/main/resources/db/migration/V20231123003_dict_data.sql
对比新文件
@@ -0,0 +1,21 @@
-- ----------------------------
-- 字典数据表
-- ----------------------------
drop table if exists `smart_assess`.`sys_dict_data`;
CREATE TABLE `smart_assess`.`sys_dict_data`  (
`id` bigint UNSIGNED NOT NULL AUTO_INCREMENT,
`sort` int NOT NULL DEFAULT 0 COMMENT '字典排序',
`label` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典标签',
`value` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典键值',
`dict_type` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '字典类型',
`is_default` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT 'N' COMMENT '是否默认(Y是 N否)',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态(0正常 1停用)',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP,
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `index_l_v_t`(`dict_type`, `label`, `value`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '字典数据表' ROW_FORMAT = Dynamic;
assess-admin/src/main/resources/db/migration/V20231123004_config.sql
对比新文件
@@ -0,0 +1,20 @@
-- ----------------------------
-- 系统配置表
-- ----------------------------
drop table if exists `smart_assess`.`sys_config`;
CREATE TABLE `smart_assess`.`sys_config`  (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL COMMENT '参数名称',
`config_key` varchar(100) NOT NULL COMMENT '参数键名',
`config_value` varchar(500) NOT NULL COMMENT '参数键值',
`type` char(1) NULL DEFAULT 'N' COMMENT '系统内置(Y是 N否)',
`create_by` varchar(64) NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_by` varchar(64) NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`remark` varchar(100) NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`),
UNIQUE INDEX `index_key`(`config_key`) USING BTREE,
UNIQUE INDEX `index_name`(`name`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统配置表' ROW_FORMAT = Dynamic;
assess-admin/src/main/resources/db/migration/V20231123005_agency.sql
对比新文件
@@ -0,0 +1,37 @@
-- ----------------------------
-- 系统机构表
-- ----------------------------
drop table if exists `smart_assess`.`sys_agency`;
CREATE TABLE `smart_assess`.`sys_agency`  (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL COMMENT '机构名称',
`credit_code` varchar(50) NOT NULL COMMENT '社会信用代码',
`attribute` tinyint(2) NOT NULL COMMENT '机构属性(0疆内,1疆外,默认0)',
`province` varchar(10) NULL DEFAULT '' COMMENT '省',
`city` varchar(20) NOT NULL COMMENT '市',
`district` varchar(20) NOT NULL COMMENT '区',
`address` varchar(100) NOT NULL COMMENT '经营地址',
`web` varchar(100) NULL DEFAULT '' COMMENT '机构网址',
`legal_person` varchar(20) NOT NULL COMMENT '法定代表人',
`legal_phone` varchar(13) NOT NULL COMMENT '法人电话',
`manager` varchar(20) NOT NULL COMMENT '机构负责人',
`manager_phone` varchar(13) NOT NULL COMMENT '负责人电话',
`cert_number` varchar(20) NOT NULL COMMENT '资质证书编号',
`issue_date` datetime NOT NULL COMMENT '发证日期',
`valid_date` datetime NOT NULL COMMENT '有效日期',
`asset_value` varchar(20) NOT NULL COMMENT '固定资产总值',
`work_area` varchar(20) NOT NULL COMMENT '工作场所建筑面积',
`archive_area` varchar(20) NOT NULL COMMENT '档案室面积',
`reg_address` varchar(100) NOT NULL COMMENT '注册地址',
`business` varchar(20) NOT NULL COMMENT '业务范围',
`report_path` varchar(50) NULL DEFAULT '' COMMENT '机构信息上报表存放路径',
`del_flag` tinyint(2) NULL DEFAULT 0 COMMENT '删除标志(0代表存在,1代表删除,默认0)',
`create_by` varchar(20) NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(20) NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(100) NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`),
INDEX `index_name`(`name`) USING BTREE
)ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '机构表' ROW_FORMAT = Dynamic;
assess-admin/src/main/resources/db/migration/V20231123006_notice.sql
对比新文件
@@ -0,0 +1,17 @@
-- ----------------------------
-- 系统通知表
-- ----------------------------
drop table if exists `smart_assess`.`sys_notice`;
CREATE TABLE `smart_assess`.`sys_notice`  (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(50) NOT NULL COMMENT '通知标题',
`content` varchar(2000) NULL DEFAULT '' COMMENT '通知内容',
`status` tinyint(2) NULL DEFAULT 0 COMMENT '通知状态(0正常,1关闭 默认0)',
`create_by` varchar(20) NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(20) NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(100) NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`)
)ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '通知表' ROW_FORMAT = Dynamic;
assess-admin/src/main/resources/db/migration/V20231123007_law.sql
对比新文件
@@ -0,0 +1,21 @@
-- ----------------------------
-- 系统法律法规表
-- ----------------------------
drop table if exists `smart_assess`.`sys_law`;
CREATE TABLE `smart_assess`.`sys_law`  (
`id` bigint NOT NULL AUTO_INCREMENT,
`title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '住标题',
`sub_title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '副标题',
`content` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '内容',
`law_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '法律法规类别',
`pub_agency` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '颁布机构',
`pub_date` datetime NOT NULL COMMENT '颁布日期',
`status` tinyint NULL DEFAULT 0 COMMENT '状态(0正常,1关闭 默认0)',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '法律法规表' ROW_FORMAT = DYNAMIC;
assess-admin/src/main/resources/db/migration/V20231124001_region.sql
对比新文件
@@ -0,0 +1,13 @@
-- ----------------------------
-- 系统地区表
-- ----------------------------
drop table if exists `smart_assess`.`sys_region`;
CREATE TABLE `smart_assess`.`sys_region`  (
`id` bigint(0) NOT NULL AUTO_INCREMENT,
`name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '地区名称',
`sort` int NULL DEFAULT 0 COMMENT '排序',
`parent_id` bigint NOT NULL DEFAULT 0 COMMENT '父主键',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `index_key`(`parent_id`, `name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统地区表' ROW_FORMAT = DYNAMIC;
assess-admin/src/main/resources/db/migration/V20231124002_attach.sql
对比新文件
@@ -0,0 +1,18 @@
-- ----------------------------
-- 系统上传文件表
-- ----------------------------
drop table if exists `smart_assess`.`sys_attach`;
CREATE TABLE `smart_assess`.`sys_attach`  (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件名称',
`path` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '文件存放路径',
`type` tinyint NOT NULL COMMENT '文件所属类型(1社保,2医保,3工资单)',
`user_id` bigint NOT NULL COMMENT '用户id',
`create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建人',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新人',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `index_name`(`name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统上传文件表' ROW_FORMAT = DYNAMIC;
assess-admin/src/main/resources/logback-spring.xml
对比新文件
@@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
    <!--引用默认日志配置-->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <!--使用默认的控制台日志输出实现-->
    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
    <!--应用名称-->
    <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
    <!-- 日志输出格式 -->
    <property name="log.pattern"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{requestId}] [%X{clientIP}] [%X{userId}] - [%C,%M,%L] - %msg%n"/>
    <property name="log.path" value="logs"/>
    <!--日志文件保存路径-->
    <property name="LOG_FILE_PATH" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/logs}"/>
    <!--LogStash访问host-->
    <springProperty name="LOG_STASH_HOST" scope="context" source="logstash.host" defaultValue="localhost"/>
    <!--是否开启LogStash插件内部日志-->
    <springProperty name="ENABLE_INNER_LOG" scope="context" source="logstash.enableInnerLog" defaultValue="false"/>
    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${log.pattern}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>
    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--        <file>${log.path}/zero-spring-info.log</file>-->
        <!-- 循环政策:基于时间创建日志文件 -->
        <!--        <file>-->
        <!--            logs/zero-spring.log-->
        <!--        </file>-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <totalSizeCap>30GB</totalSizeCap>
            <!--设置日志文件大小,超过就重新生成文件,默认50M-->
            <maxFileSize>100MB</maxFileSize>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
            <charset>UTF-8</charset>
        </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}/zero-spring-error.log</file>-->
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/${APP_NAME}-error-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
            <totalSizeCap>10GB</totalSizeCap>
            <!--设置日志文件大小,超过就重新生成文件,默认50M-->
            <maxFileSize>100MB</maxFileSize>
            <!-- 日志最大的历史 30天 -->
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
            <charset>UTF-8</charset>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>
    <!--控制框架输出日志-->
    <logger name="org.slf4j" level="INFO"/>
    <logger name="springfox" level="INFO"/>
    <logger name="io.swagger" level="INFO"/>
    <logger name="org.springframework" level="INFO"/>
    <logger name="org.hibernate.validator" level="INFO"/>
    <root level="INFO">
<!--        <appender-ref ref="console"/>-->
        <appender-ref ref="file_info"/>
        <appender-ref ref="file_error"/>
    </root>
    <root level="DEBUG">
        <appender-ref ref="console"/>
    </root>
</configuration>
assess-admin/src/test/java/com/gkhy/admin/MybatisPlusGenerator.java
对比新文件
@@ -0,0 +1,109 @@
package com.gkhy.admin;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MybatisPlusGenerator {
    public static void main(String[] args) {
        System.out.println(System.getProperty("user.dir"));
        String model="/assess-system";
        // 数据库配置
        DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig
                .Builder("jdbc:mysql://localhost:3306/smart_assess" +
                "?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true"
                , "root", "password");
        FastAutoGenerator.create(dataSourceConfigBuilder)
                // 全局配置
                .globalConfig((scanner, builder) -> {
                    builder.author("kzy")
                            // 覆盖已生成文件
                            .fileOverride()
                            // 指定输出目录
                            .outputDir(System.getProperty("user.dir") +model+ "/src/main/java/")
                            // 开启 swagger 模式
                            .enableSwagger()
                            // 禁止打开输出目录
                            .disableOpenDir()
                            // 时间策略
                            .dateType(DateType.TIME_PACK)
                            // 类注释日期的格式
                            .commentDate("yyyy-MM-dd HH:mm:ss")
                            .build();
                })
                // 包配置
                .packageConfig((scanner, builder) -> {
                    // 父包名
                    builder.parent("com.gkhy.assess")
                            // 模块名
                            .moduleName("system")
                            // Entity 包名
                            .entity("domain")
                            // Service 包名
                            .service("service")
                            //    Service Impl 包名
                            .serviceImpl("service.impl")
                            // Controller 包名
                            .controller("controller")
                            // Mapper 包名
                            .mapper("mapper.system")
                            // MapperXML 包名
                            .xml("mapper.system")
                            // 路径配置信息
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") +model+ "/src/main/resources/mapper/"));
                })
                //策略配置
                .strategyConfig((scanner, builder) -> {
                    // 增加表匹配(内存过滤),    include 与 exclude 只能配置一项
                    builder.addInclude(getTables(scanner.apply("请输入要生成的表名,多个英文逗号分隔?所有输入 all")))
                            //     增加表排除匹配(内存过滤),    include 与 exclude 只能配置一项
                            // .addExclude(scanner.apply("请输入要忽略的表名,多个英文逗号分隔?"))
                            //     增加过滤表后缀
                            .addTableSuffix("")
                            //     增加过滤表前缀
                            .addTablePrefix("")
                            // service 策略配置
                            .serviceBuilder()
                            //     格式化文件名称
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            // 实体策略配置
                            .entityBuilder()
                            // 开启 lombok 模型
                            .enableLombok()
                            // 开启生成实体时生成字段注解
                            .enableTableFieldAnnotation()
                            // controller 策略配置
                            .controllerBuilder()
                            .formatFileName("%sController")
                            // 开启生成@RestController 控制器
                            .enableRestStyle()
                            //     mapper 策略配置
                            .mapperBuilder()
                            .formatMapperFileName("%sMapper")
                            .enableMapperAnnotation()
                            .formatXmlFileName("%sMapper");
                })
                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }
    /**
     * 处理 all 情况
     *
     * @param tables
     * @return
     */
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}
assess-common/pom.xml
对比新文件
@@ -0,0 +1,112 @@
<?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.gkhy.assess</groupId>
        <artifactId>smart_assess</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>assess-common</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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- Spring框架基本的核心工具 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <!--MyBatis分页插件-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
        </dependency>
        <!--常用工具类 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
        </dependency>
        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
        </dependency>
        <!--数据库版本管理-->
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.flywaydb</groupId>
            <artifactId>flyway-mysql</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring-boot-web-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.crazycake</groupId>
            <artifactId>shiro-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
        </dependency>
    </dependencies>
</project>
assess-common/src/main/java/com/gkhy/assess/common/annotation/DataScope.java
对比新文件
@@ -0,0 +1,30 @@
package com.gkhy.assess.common.annotation;
import java.lang.annotation.*;
/**
 * 数据权限过滤注解
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope {
    /**
     * 部门表的别名
     * @return
     */
    public String deptAlias() default "";
    /**
     * 用户表的别名
     * @return
     */
    public String userAlias() default "";
    /**
     * 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@RequiresPermissions获取,多个权限用逗号分隔开来
     * @return
     */
    public String permission() default "";
}
assess-common/src/main/java/com/gkhy/assess/common/annotation/DataSource.java
对比新文件
@@ -0,0 +1,23 @@
package com.gkhy.assess.common.annotation;
import com.gkhy.assess.common.enums.DataSourceTypeEnum;
import java.lang.annotation.*;
/**
 * 自定义多数据源切换注解
 *
 * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource {
    /**
     * 切换数据源名称
     * @return
     */
    public DataSourceTypeEnum value() default DataSourceTypeEnum.MASTER;
}
assess-common/src/main/java/com/gkhy/assess/common/annotation/RepeatSubmit.java
对比新文件
@@ -0,0 +1,23 @@
package com.gkhy.assess.common.annotation;
import java.lang.annotation.*;
/**
 * 自定义注解防止表单重复提交
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeatSubmit {
    /**
     * 间隔时间(ms) 小于此时间视为重复提交
     * @return
     */
    public int interval() default 5000;
    /**
     * 提示消息
     * @return
     */
    public String message() default "不允许重复提交,请稍后再试";
}
assess-common/src/main/java/com/gkhy/assess/common/api/CommonPage.java
对比新文件
@@ -0,0 +1,88 @@
package com.gkhy.assess.common.api;
import com.github.pagehelper.PageInfo;
import java.util.List;
/**
 * 通用分页数据封装
 */
public class CommonPage <T>{
    /**
     * 当前页码
     */
    private Integer pageNum;
    /**
     * 每页数量
     */
    private Integer pageSize;
    /**
     * 总页数
     */
    private Integer totalPage;
    /**
     * 总条数
     */
    private Long total;
    /**
     * 分页数据
     */
    private List<T> list;
    /**
     * 将PageHelper分页后的list转为分页信息
     */
    public static <T> CommonPage<T> restPage(List<T> list) {
        CommonPage<T> result = new CommonPage<T>();
        PageInfo<T> pageInfo = new PageInfo<T>(list);
        result.setTotalPage(pageInfo.getPages());
        result.setPageNum(pageInfo.getPageNum());
        result.setPageSize(pageInfo.getPageSize());
        result.setTotal(pageInfo.getTotal());
        result.setList(pageInfo.getList());
        return result;
    }
    public Integer getPageNum() {
        return pageNum;
    }
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }
    public Integer getPageSize() {
        return pageSize;
    }
    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
    public Integer getTotalPage() {
        return totalPage;
    }
    public void setTotalPage(Integer totalPage) {
        this.totalPage = totalPage;
    }
    public List<T> getList() {
        return list;
    }
    public void setList(List<T> list) {
        this.list = list;
    }
    public Long getTotal() {
        return total;
    }
    public void setTotal(Long total) {
        this.total = total;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/api/CommonResult.java
对比新文件
@@ -0,0 +1,143 @@
package com.gkhy.assess.common.api;
/**
 * 通用返回结果封装类
 * @param <T>
 */
public class CommonResult<T> {
    /**
     * 状态码
     */
    private int code;
    /**
     * 提示消息
     */
    private String message;
    /**
     * 数据封装
     */
    private T data;
    protected CommonResult(){
    }
    protected CommonResult(int code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }
    /**
     * 成功返回结果
     *
     */
    public static <T> CommonResult<T> success(){
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(),ResultCode.SUCCESS.getMessage(),null);
    }
    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     */
    public static <T> CommonResult<T> success(T data){
        return new CommonResult<T>(ResultCode.SUCCESS.getCode(),ResultCode.SUCCESS.getMessage(),data);
    }
    /**
     * 成功返回结果
     *
     * @param data 获取的数据
     * @param  message 提示信息
     */
    public static <T> CommonResult<T> success(T data,String message){
        return new CommonResult<>(ResultCode.SUCCESS.getCode(),message,data);
    }
    /**
     * 失败返回结果
     * @param errorCode 错误码
     */
    public static <T> CommonResult<T> failed(IErrorCode errorCode){
        return new CommonResult<>(errorCode.getCode(),errorCode.getMessage(),null);
    }
    /**
     * 失败返回结果
     * @param errorCode 错误码
     * @param message 错误信息
     */
    public static <T> CommonResult<T> failed(IErrorCode errorCode,String message){
        return new CommonResult<>(errorCode.getCode(),message,null);
    }
    /**
     * 失败返回结果
     * @param message 提示信息
     */
    public static <T> CommonResult<T> failed(String message){
        return new CommonResult<>(ResultCode.FAILED.getCode(), message,null);
    }
    /**
     * 失败返回结果
     */
    public static <T> CommonResult<T> failed(){
        return failed(ResultCode.FAILED);
    }
    /**
     * 参数验证失败返回结果
     */
    public static <T> CommonResult<T> validateFailed() {
        return failed(ResultCode.VALIDATE_FAILED);
    }
    /**
     * 参数验证失败返回结果
     * @param message 提示信息
     */
    public static <T> CommonResult<T> validateFailed(String message) {
        return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getCode(), message, null);
    }
    /**
     * 未登录返回结果
     */
    public static <T> CommonResult<T> unauthorized(T data) {
        return new CommonResult<T>(ResultCode.UNAUTHORIZED.getCode(), ResultCode.UNAUTHORIZED.getMessage(), data);
    }
    /**
     * 未授权返回结果
     */
    public static <T> CommonResult<T> forbidden(T data) {
        return new CommonResult<T>(ResultCode.FORBIDDEN.getCode(), ResultCode.FORBIDDEN.getMessage(), data);
    }
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public T getData() {
        return data;
    }
    public void setData(T data) {
        this.data = data;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/api/IErrorCode.java
对比新文件
@@ -0,0 +1,16 @@
package com.gkhy.assess.common.api;
/**
 * API返回码接口
 */
public interface IErrorCode {
    /**
     * 返回码
     */
    int getCode();
    /**
     * 返回信息
     */
    String getMessage();
}
assess-common/src/main/java/com/gkhy/assess/common/api/ResultCode.java
对比新文件
@@ -0,0 +1,30 @@
package com.gkhy.assess.common.api;
/**
 * API返回码封装
 */
public enum ResultCode implements IErrorCode {
    SUCCESS(200,"操作成功"),
    FAILED(500, "操作失败"),
    VALIDATE_FAILED(404, "参数检验失败"),
    UNAUTHORIZED(401, "暂未登录或token已经过期"),
    FORBIDDEN(403, "没有相关权限");
    private int code;
    private String message;
    private ResultCode(int code,String message){
        this.code=code;
        this.message=message;
    }
    @Override
    public int getCode() {
        return code;
    }
    @Override
    public String getMessage() {
        return message;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/BaseFlywayConfig.java
对比新文件
@@ -0,0 +1,28 @@
package com.gkhy.assess.common.config;
import cn.hutool.extra.spring.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
import javax.sql.DataSource;
@Slf4j
public class BaseFlywayConfig {
    public void initDataSource(String dataSourceName){
        Flyway flyway = Flyway.configure()
                .dataSource(SpringUtil.getBean(dataSourceName,DataSource.class))
                .locations("classpath:db/migration")
                .encoding("UTF-8")
                .outOfOrder(true)
                .cleanDisabled(true)
                .cleanOnValidationError(false)
                .sqlMigrationPrefix("V")
                .sqlMigrationSeparator("_")
                .sqlMigrationSuffixes(".sql")
                .validateOnMigrate(true)
                .baselineOnMigrate(true)
                .load();
        flyway.migrate();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/BaseRedisConfig.java
对比新文件
@@ -0,0 +1,72 @@
package com.gkhy.assess.common.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.gkhy.assess.common.service.RedisService;
import com.gkhy.assess.common.service.impl.RedisServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
/**
 * Redis基础配置
 */
public class BaseRedisConfig {
    /**
     * 配置redisTemplate
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisSerializer<Object> serializer=redisSerializer();
        RedisTemplate<String,Object> redisTemplate=new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(serializer);
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(serializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
    @Bean
    public RedisSerializer<Object> redisSerializer(){
        //创建JSON序列化器
        Jackson2JsonRedisSerializer<Object> serializer=new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper=new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //必须设置,否则无法将JSON转化为对象,会转化成Map类型
        objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }
    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory redisConnectionFactory){
        RedisCacheWriter redisCacheWriter=RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);
        //设置Redis缓存有效期为1天
        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer())).entryTtl(Duration.ofDays(1));
        return new RedisCacheManager(redisCacheWriter, redisCacheConfiguration);
    }
    @Bean
    public RedisService redisService(){
        return new RedisServiceImpl();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/BaseSwaggerConfig.java
对比新文件
@@ -0,0 +1,63 @@
package com.gkhy.assess.common.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
/**
 * Swagger2的接口配置
 *
 */
public class BaseSwaggerConfig
{
    /** 是否开启swagger */
    @Value("${swagger.enabled:false}")
    private boolean enabled;
    /**
     * 创建API
     */
    @Bean
    public Docket createRestApi()
    {
        return new Docket(DocumentationType.SWAGGER_2)
                // 是否启用Swagger
                .enable(enabled)
                // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
                .apiInfo(apiInfo())
                // 设置哪些接口暴露给Swagger展示
                .select()
                // 扫描所有有注解的api,用这种方式更灵活
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
                // 扫描指定包中的swagger注解
                //.apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger"))
                // 扫描所有 .apis(RequestHandlerSelectors.any())
                .paths(PathSelectors.any())
                .build();
    }
    /**
     * 添加摘要信息
     */
    private ApiInfo apiInfo()
    {
        // 用ApiInfoBuilder进行定制
        return new ApiInfoBuilder()
                // 设置标题
                .title("xx系统单机版API文档")
                // 描述
                .description("描述:xx系统单机版API文档")
                // 作者信息
                .contact(new Contact("nms", null, null))
                // 版本
                .version("版本号:1.0")
                .build();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/CaffeineConfig.java
对比新文件
@@ -0,0 +1,37 @@
package com.gkhy.assess.common.config;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.cache.CacheManager;
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;
public class CaffeineConfig {
    /**
     * 系统默认缓存TTL时间:10分钟
     */
    public static final long SYSTEM_DEFAULT_EXPIRES = 10 * 60 * 1000;
    @Bean
    public Cache<String,Object> caffeineCache(){
        return Caffeine.newBuilder()
                // 设置最后一次写入或访问后经过固定时间过期
                .expireAfterWrite(SYSTEM_DEFAULT_EXPIRES, TimeUnit.MILLISECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(10000)
                .build();
    }
    //@Bean
    public CacheManager cacheManager() {
        // create and return an instance of your preferred cache manager, for example:
        return new ConcurrentMapCacheManager();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/DynamicDataSourceContextHolder.java
对比新文件
@@ -0,0 +1,40 @@
package com.gkhy.assess.common.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
 * 动态数据库切换处理
 */
public class DynamicDataSourceContextHolder {
    public static final Logger logger= LoggerFactory.getLogger(DynamicDataSourceContextHolder.class);
    /**
     * 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
     * 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
     */
    private static final ThreadLocal<String> CONTEXT_HOLDER=new ThreadLocal<>();
    /**
     * 设置数据源的变量
     */
    public static void setDataSourceType(String dsType){
        logger.info("切换到{}数据源",dsType);
        CONTEXT_HOLDER.set(dsType);
    }
    /**
     * 获得数据源的变量
     */
    public static String getDataSourceType(){
        return CONTEXT_HOLDER.get();
    }
    /**
     * 清空数据源变量
     */
    public static void clearDataSourceType(){
        CONTEXT_HOLDER.remove();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/MybatisPlusConfig.java
对比新文件
@@ -0,0 +1,40 @@
package com.gkhy.assess.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.github.pagehelper.PageHelper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
@Configuration
public class MybatisPlusConfig {
    /**
     * 新的分页插件,一缓和二缓遵循mybatis的规则,
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        paginationInnerInterceptor.setOverflow(false);//溢出总页数 总是跳到第一页
        interceptor.addInnerInterceptor(paginationInnerInterceptor);
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
    @Bean
    public PageHelper pageHelper() {
        PageHelper pageHelper = new PageHelper();
        //添加配置,也可以指定文件路径
        Properties p = new Properties();
        p.setProperty("offsetAsPageNum", "true");
        p.setProperty("rowBoundsWithCount", "true");
        p.setProperty("reasonable", "true");
        pageHelper.setProperties(p);
        return pageHelper;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/config/ThreadPoolConfig.java
对比新文件
@@ -0,0 +1,50 @@
package com.gkhy.assess.common.config;
import com.gkhy.assess.common.utils.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class ThreadPoolConfig {
    //核心线程池大小
    private int corePoolSize=50;
    //最大可创建的线程数
    private int maxPoolSize=200;
    //队列最大长度
    private int queueCapacity=1000;
    //线程池维护非线程允许的空闲时间
    private int keepAliveSeconds=300;
    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        executor.setMaxPoolSize(maxPoolSize);
        executor.setCorePoolSize(corePoolSize);
        executor.setQueueCapacity(queueCapacity);
        executor.setKeepAliveSeconds(keepAliveSeconds);
        // 线程池对拒绝任务(无线程可用)的处理策略
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
    public ScheduledExecutorService scheduledExecutorService(){
        return new ScheduledThreadPoolExecutor(corePoolSize,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
               new ThreadPoolExecutor.CallerRunsPolicy()){
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                Threads.printException(r,t);
            }
        };
    }
}
assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java
对比新文件
@@ -0,0 +1,17 @@
package com.gkhy.assess.common.constant;
public interface CacheConstant {
    String SYS_LOGIN_RECORD_CACHE="login_record_cache";
    String SYS_USER_TOKEN="prefix_user_token";
    String SYS_USER_NAME="username";
    String SYS_CONFIG_CACHE="sys-config";
    String SYS_CONFIG_KEY = "sys_config:";
}
assess-common/src/main/java/com/gkhy/assess/common/domain/BaseEntity.java
对比新文件
@@ -0,0 +1,59 @@
package com.gkhy.assess.common.domain;
import com.baomidou.mybatisplus.annotation.TableField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@Getter
@Setter
@ApiModel(value = "baseEntity对象", description = "基础类")
public class BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty("创建者")
    @TableField("create_by")
    private String createBy;
    @ApiModelProperty("创建时间")
    @TableField("create_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime createTime;
    @ApiModelProperty("更新者")
    @TableField("update_by")
    private String updateBy;
    @ApiModelProperty("更新时间")
    @TableField("update_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
    private LocalDateTime updateTime;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
    /** 请求参数 */
    @TableField(exist = false)
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private Map<String, Object> params;
    public Map<String, Object> getParams()
    {
        if (params == null)
        {
            params = new HashMap<>();
        }
        return params;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/domain/PageDomain.java
对比新文件
@@ -0,0 +1,66 @@
package com.gkhy.assess.common.domain;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.StringUtils;
public class PageDomain {
    private Integer pageNum;
    private Integer pageSize;
    private String orderByColumn;
    private String isAsc="asc";
    private Boolean reasonable=true;
    public String getOrderBy(){
        if(StrUtil.isEmpty(orderByColumn)){
            return "";
        }
        return StrUtil.toUnderlineCase(orderByColumn)+" "+isAsc;
    }
    public Integer getPageNum() {
        return pageNum;
    }
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum;
    }
    public Integer getPageSize() {
        return pageSize;
    }
    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
    public String getOrderByColumn() {
        return orderByColumn;
    }
    public void setOrderByColumn(String orderByColumn) {
        this.orderByColumn = orderByColumn;
    }
    public String getIsAsc() {
        return isAsc;
    }
    public void setIsAsc(String isAsc) {
        this.isAsc = isAsc;
    }
    public Boolean getReasonable() {
        if(reasonable==null){
            return Boolean.TRUE;
        }
        return reasonable;
    }
    public void setReasonable(Boolean reasonable) {
        this.reasonable = reasonable;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/domain/TableSupport.java
对比新文件
@@ -0,0 +1,56 @@
package com.gkhy.assess.common.domain;
import cn.hutool.core.convert.Convert;
import com.gkhy.assess.common.utils.ServletUtil;
/**
 * 表格数据处理
 *
 */
public class TableSupport
{
    /**
     * 当前记录起始索引
     */
    public static final String PAGE_NUM = "pageNum";
    /**
     * 每页显示记录数
     */
    public static final String PAGE_SIZE = "pageSize";
    /**
     * 排序列
     */
    public static final String ORDER_BY_COLUMN = "orderByColumn";
    /**
     * 排序的方向 "desc" 或者 "asc".
     */
    public static final String IS_ASC = "isAsc";
    /**
     * 分页参数合理化
     */
    public static final String REASONABLE = "reasonable";
    /**
     * 封装分页对象
     */
    public static PageDomain getPageDomain()
    {
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageNum(Convert.toInt(ServletUtil.getParameter(PAGE_NUM), 1));
        pageDomain.setPageSize(Convert.toInt(ServletUtil.getParameter(PAGE_SIZE), 10));
        pageDomain.setOrderByColumn(ServletUtil.getParameter(ORDER_BY_COLUMN));
        pageDomain.setIsAsc(ServletUtil.getParameter(IS_ASC));
        pageDomain.setReasonable(ServletUtil.getParameterToBool(REASONABLE));
        return pageDomain;
    }
    public static PageDomain buildPageRequest()
    {
        return getPageDomain();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/domain/WebLog.java
对比新文件
@@ -0,0 +1,67 @@
package com.gkhy.assess.common.domain;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
 * Controller层的日志封装类
 */
@Data
@EqualsAndHashCode
public class WebLog {
    /**
     * 操作描述
     */
    private String description;
    /**
     * 操作用户
     */
    private String username;
    /**
     * 操作时间
     */
    private Long startTime;
    /**
     * 消耗时间
     */
    private Integer spendTime;
    /**
     * 根路径
     */
    private String basePath;
    /**
     * URI
     */
    private String uri;
    /**
     * URL
     */
    private String url;
    /**
     * 请求类型
     */
    private String method;
    /**
     * IP地址
     */
    private String ip;
    /**
     * 请求参数
     */
    private Object parameter;
    /**
     * 返回结果
     */
    private Object result;
}
assess-common/src/main/java/com/gkhy/assess/common/domain/vo/AccountVO.java
对比新文件
@@ -0,0 +1,34 @@
package com.gkhy.assess.common.domain.vo;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import java.io.Serializable;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
@Getter
@Setter
@ApiModel(value = "用户账号对象", description = "用户账号对象")
@JsonInclude(NON_NULL)
public class AccountVO implements Serializable {
    private static final long serialVersionUID = 1L;
    @ApiModelProperty(value = "用户id",required = true)
    private Long id;
    @ApiModelProperty(value = "登录名",required = true)
    private String username;
    @ApiModelProperty(value = "用户昵称",required = true)
    private String name;
    @ApiModelProperty("用户角色")
    private String role;
    @ApiModelProperty("生产的token,接口请求头字段: Authorization")
    private String token;
}
assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java
对比新文件
@@ -0,0 +1,24 @@
package com.gkhy.assess.common.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
@Getter
@Setter
@ApiModel(value = "登录提交表单", description = "登录提交表单")
public class LoginBody {
    @ApiModelProperty(value = "登录名",required = true)
    @NotBlank(message = "登录名不能为空")
    private String username;
    @ApiModelProperty(value = "密码",required = true)
    @NotBlank(message = "密码不能为空")
    private String password;
    @ApiModelProperty(value = "验证码",required = false)
    private String code;
    @ApiModelProperty(value = "唯一标识",required = false)
    private String uuid;
}
assess-common/src/main/java/com/gkhy/assess/common/enums/ApproveStatusEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 审批状态
 *
 */
public enum ApproveStatusEnum
{
    APPROVED(0, "审批通过"), APPROVING(1, "待审批"), FAIL(2, "未通过");
    private final Integer code;
    private final String info;
    ApproveStatusEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/DataSourceTypeEnum.java
对比新文件
@@ -0,0 +1,15 @@
package com.gkhy.assess.common.enums;
/**
 * 数据源
 */
public enum DataSourceTypeEnum {
    /**
     * 主库
     */
    MASTER,
    /**
     * 从库
     */
    SLAVE
}
assess-common/src/main/java/com/gkhy/assess/common/enums/DeleteFlagEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 删除状态
 *
 */
public enum DeleteFlagEnum
{
    UN_DELETE(0, "未删除"), DELETED(1, "已删除");
    private final Integer code;
    private final String info;
    DeleteFlagEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/SocialSameEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 社保一致性
 *
 */
public enum SocialSameEnum
{
    SAME(0, "一致"), NOT_SAME(1, "不一致");
    private final Integer code;
    private final String info;
    SocialSameEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/UserIdentityEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 用户身份
 *
 */
public enum UserIdentityEnum
{
    MONITOR(0, "监管用户"), AGENCY(1, "机构用户"), EXPERT(2, "专家用户");
    private final Integer code;
    private final String info;
    UserIdentityEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/UserSexEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 用户性别
 *
 */
public enum UserSexEnum
{
    MAN(0, "男"), AGENCY(1, "女"), EXPERT(2, "未知");
    private final Integer code;
    private final String info;
    UserSexEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/UserStatusEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 用户状态
 *
 */
public enum UserStatusEnum
{
    OK(0, "正常"), DISABLE(1, "停用"), DELETED(1, "删除");
    private final Integer code;
    private final String info;
    UserStatusEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/enums/UserTypeEnum.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.enums;
/**
 * 用户类型
 *
 */
public enum UserTypeEnum
{
    WORKER(0, "工作人员"), LEADER(1, "领导");
    private final Integer code;
    private final String info;
    UserTypeEnum(Integer code, String info)
    {
        this.code = code;
        this.info = info;
    }
    public Integer getCode()
    {
        return code;
    }
    public String getInfo()
    {
        return info;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/exception/ApiException.java
对比新文件
@@ -0,0 +1,31 @@
package com.gkhy.assess.common.exception;
import com.gkhy.assess.common.api.IErrorCode;
/**
 * 自定义API异常
 */
public class ApiException extends RuntimeException{
    private IErrorCode errorCode;
    public ApiException(IErrorCode errorCode) {
        super(errorCode.getMessage());
        this.errorCode = errorCode;
    }
    public ApiException(String message) {
        super(message);
    }
    public ApiException(Throwable cause) {
        super(cause);
    }
    public ApiException(String message, Throwable cause) {
        super(message, cause);
    }
    public IErrorCode getErrorCode() {
        return errorCode;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/exception/UtilException.java
对比新文件
@@ -0,0 +1,29 @@
package com.gkhy.assess.common.exception;
import com.gkhy.assess.common.api.IErrorCode;
public class UtilException extends RuntimeException{
    private IErrorCode errorCode;
    public UtilException(IErrorCode errorCode){
        super(errorCode.getMessage());
        this.errorCode = errorCode;
    }
    public UtilException(String message){
        super(message);
    }
    public UtilException(Throwable cause){
        super(cause);
    }
    public UtilException(String message, Throwable cause) {
        super(message, cause);
    }
    public IErrorCode getErrorCode() {
        return errorCode;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/service/RedisService.java
对比新文件
@@ -0,0 +1,181 @@
package com.gkhy.assess.common.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
 * Redis操作Service
 */
public interface RedisService {
    /**
     * 保存属性
     */
    void set(String key, Object value, long time);
    /**
     * 保存属性
     */
    void set(String key, Object value);
    /**
     * 获取属性
     */
    Object get(String key);
    /**
     * 删除属性
     */
    Boolean del(String key);
    /**
     * 批量删除属性
     */
    Long del(List<String> keys);
    /**
     * 设置过期时间
     */
    Boolean expire(String key, long time);
    /**
     * 获取过期时间
     */
    Long getExpire(String key);
    /**
     * 判断是否有该属性
     */
    Boolean hasKey(String key);
    /**
     * 按delta递增
     */
    Long incr(String key, long delta);
    /**
     * 按delta递减
     */
    Long decr(String key, long delta);
    /**
     * 获取Hash结构中的属性
     */
    Object hGet(String key, String hashKey);
    /**
     * 向Hash结构中放入一个属性
     */
    Boolean hSet(String key, String hashKey, Object value, long time);
    /**
     * 向Hash结构中放入一个属性
     */
    void hSet(String key, String hashKey, Object value);
    /**
     * 直接获取整个Hash结构
     */
    Map<Object, Object> hGetAll(String key);
    /**
     * 直接设置整个Hash结构
     */
    Boolean hSetAll(String key, Map<String, Object> map, long time);
    /**
     * 直接设置整个Hash结构
     */
    void hSetAll(String key, Map<String, ?> map);
    /**
     * 删除Hash结构中的属性
     */
    void hDel(String key, Object... hashKey);
    /**
     * 判断Hash结构中是否有该属性
     */
    Boolean hHasKey(String key, String hashKey);
    /**
     * Hash结构中属性递增
     */
    Long hIncr(String key, String hashKey, Long delta);
    /**
     * Hash结构中属性递减
     */
    Long hDecr(String key, String hashKey, Long delta);
    /**
     * 获取Set结构
     */
    Set<Object> sMembers(String key);
    /**
     * 向Set结构中添加属性
     */
    Long sAdd(String key, Object... values);
    /**
     * 向Set结构中添加属性
     */
    Long sAdd(String key, long time, Object... values);
    /**
     * 是否为Set中的属性
     */
    Boolean sIsMember(String key, Object value);
    /**
     * 获取Set结构的长度
     */
    Long sSize(String key);
    /**
     * 删除Set结构中的属性
     */
    Long sRemove(String key, Object... values);
    /**
     * 获取List结构中的属性
     */
    List<Object> lRange(String key, long start, long end);
    /**
     * 获取List结构的长度
     */
    Long lSize(String key);
    /**
     * 根据索引获取List中的属性
     */
    Object lIndex(String key, long index);
    /**
     * 向List结构中添加属性
     */
    Long lPush(String key, Object value);
    /**
     * 向List结构中添加属性
     */
    Long lPush(String key, Object value, long time);
    /**
     * 向List结构中批量添加属性
     */
    Long lPushAll(String key, Object... values);
    /**
     * 向List结构中批量添加属性
     */
    Long lPushAll(String key, Long time, Object... values);
    /**
     * 从List结构中移除属性
     */
    Long lRemove(String key, long count, Object value);
}
assess-common/src/main/java/com/gkhy/assess/common/service/impl/RedisServiceImpl.java
对比新文件
@@ -0,0 +1,197 @@
package com.gkhy.assess.common.service.impl;
import com.gkhy.assess.common.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
 * Redis操作Service实现类
 */
public class RedisServiceImpl implements RedisService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Override
    public void set(String key, Object value, long time) {
        redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
    }
    @Override
    public void set(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }
    @Override
    public Object get(String key) {
        return redisTemplate.opsForValue().get(key);
    }
    @Override
    public Boolean del(String key) {
        return redisTemplate.delete(key);
    }
    @Override
    public Long del(List<String> keys) {
        return redisTemplate.delete(keys);
    }
    @Override
    public Boolean expire(String key, long time) {
        return redisTemplate.expire(key, time, TimeUnit.SECONDS);
    }
    @Override
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    @Override
    public Boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }
    @Override
    public Long incr(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, delta);
    }
    @Override
    public Long decr(String key, long delta) {
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    @Override
    public Object hGet(String key, String hashKey) {
        return redisTemplate.opsForHash().get(key, hashKey);
    }
    @Override
    public Boolean hSet(String key, String hashKey, Object value, long time) {
        redisTemplate.opsForHash().put(key, hashKey, value);
        return expire(key, time);
    }
    @Override
    public void hSet(String key, String hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }
    @Override
    public Map<Object, Object> hGetAll(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    @Override
    public Boolean hSetAll(String key, Map<String, Object> map, long time) {
        redisTemplate.opsForHash().putAll(key, map);
        return expire(key, time);
    }
    @Override
    public void hSetAll(String key, Map<String, ?> map) {
        redisTemplate.opsForHash().putAll(key, map);
    }
    @Override
    public void hDel(String key, Object... hashKey) {
        redisTemplate.opsForHash().delete(key, hashKey);
    }
    @Override
    public Boolean hHasKey(String key, String hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }
    @Override
    public Long hIncr(String key, String hashKey, Long delta) {
        return redisTemplate.opsForHash().increment(key, hashKey, delta);
    }
    @Override
    public Long hDecr(String key, String hashKey, Long delta) {
        return redisTemplate.opsForHash().increment(key, hashKey, -delta);
    }
    @Override
    public Set<Object> sMembers(String key) {
        return redisTemplate.opsForSet().members(key);
    }
    @Override
    public Long sAdd(String key, Object... values) {
        return redisTemplate.opsForSet().add(key, values);
    }
    @Override
    public Long sAdd(String key, long time, Object... values) {
        Long count = redisTemplate.opsForSet().add(key, values);
        expire(key, time);
        return count;
    }
    @Override
    public Boolean sIsMember(String key, Object value) {
        return redisTemplate.opsForSet().isMember(key, value);
    }
    @Override
    public Long sSize(String key) {
        return redisTemplate.opsForSet().size(key);
    }
    @Override
    public Long sRemove(String key, Object... values) {
        return redisTemplate.opsForSet().remove(key, values);
    }
    @Override
    public List<Object> lRange(String key, long start, long end) {
        return redisTemplate.opsForList().range(key, start, end);
    }
    @Override
    public Long lSize(String key) {
        return redisTemplate.opsForList().size(key);
    }
    @Override
    public Object lIndex(String key, long index) {
        return redisTemplate.opsForList().index(key, index);
    }
    @Override
    public Long lPush(String key, Object value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }
    @Override
    public Long lPush(String key, Object value, long time) {
        Long index = redisTemplate.opsForList().rightPush(key, value);
        expire(key, time);
        return index;
    }
    @Override
    public Long lPushAll(String key, Object... values) {
        return redisTemplate.opsForList().rightPushAll(key, values);
    }
    @Override
    public Long lPushAll(String key, Long time, Object... values) {
        Long count = redisTemplate.opsForList().rightPushAll(key, values);
        expire(key, time);
        return count;
    }
    @Override
    public Long lRemove(String key, long count, Object value) {
        return redisTemplate.opsForList().remove(key, count, value);
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/BeanValidators.java
对比新文件
@@ -0,0 +1,19 @@
package com.gkhy.assess.common.utils;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Set;
/**
 * bean对象属性校验
 */
public class BeanValidators {
    public static void validateWithException(Validator validator,Object object,Class<?>... groups) throws ConstraintViolationException{
        Set<ConstraintViolation<Object>> constraintViolationSet=validator.validate(object,groups);
        if(!constraintViolationSet.isEmpty()){
            throw new ConstraintViolationException(constraintViolationSet);
        }
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/CommonUtil.java
对比新文件
@@ -0,0 +1,5 @@
package com.gkhy.assess.common.utils;
public class CommonUtil {
}
assess-common/src/main/java/com/gkhy/assess/common/utils/ConvertUtil.java
对比新文件
@@ -0,0 +1,990 @@
package com.gkhy.assess.common.utils;
import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.ArrayUtils;
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;
/**
 * 类型转换器
 *
 */
public class ConvertUtil
{
    /**
     * 转换为字符串<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 StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 split 被转换的值
     * @return 结果
     */
    public static Integer[] toIntArray(String split, String str)
    {
        if (StrUtil.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 (StrUtil.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 split 被转换的值
     * @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 (StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 (StrUtil.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 对象
     * @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[])
        {
            return str((byte[]) obj, charset);
        }
        else if (obj instanceof Byte[])
        {
            byte[] bytes = ArrayUtils.toPrimitive((Byte[]) obj);
            return str(bytes, 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, StrUtil.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);
            }
        }
        String returnString = new String(c);
        return returnString;
    }
    /**
     * 数字金额大写转换 先写个完整的然后将如零拾替换成零
     *
     * @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("^整$", "零元整");
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/JwtTokenUtil.java
对比新文件
@@ -0,0 +1,115 @@
package com.gkhy.assess.common.utils;
import cn.hutool.crypto.digest.DigestUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gkhy.assess.common.exception.ApiException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
 * JwtToken生成的工具类
 * JWT token的格式:header.payload.signature
 * header的格式(算法、token的类型):
 * {"alg": "HS512","typ": "JWT"}
 * payload的格式(用户名、创建时间、生成时间):
 * {"sub":"wang","created":1489079981393,"exp":1489684781}
 * signature的生成算法:
 * HMACSHA512(base64UrlEncode(header) + "." +base64UrlEncode(payload),secret)
 */
public class JwtTokenUtil {
    private static final Logger LOGGER = LoggerFactory.getLogger(JwtTokenUtil.class);
    public static final String USER_LOGIN_TOKEN="Authorization";
    public static final String CLAIM_KEY_USERNAME = "sub";
    public static final String CLAIM_KEY_CREATED = "created";
    public static String SECRET="nms-secret";
    public static String tokenHead="";
    /**Token有效期为7天(Token在reids中缓存时间为两倍)*/
    public static final long EXPIRATION=(7 * 12) * 60 * 60 * 1000;  //JWT的超期限时间(60*60*24*7)
    /**
     * 校验token是否正确
     * @param token
     * @param username
     * @param secret  用户密码
     * @return
     */
    public static boolean verify(String token,String username,String secret){
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build();
            DecodedJWT jwt = verifier.verify(token);
            return true;
        }catch (Exception e){
            return false;
        }
    }
    /**
     * 获取token中的信息  无需secret解密也能获得
     * @param token
     * @return
     */
    public static String getUsername(String token){
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        }catch (JWTDecodeException e){
            return null;
        }
    }
    /**
     * 生成签名
     * @param username
     * @param secret
     * @return
     */
    public static String sign(String username,String secret){
        Date date=new Date(System.currentTimeMillis()+EXPIRATION*1000);
        Algorithm algorithm=Algorithm.HMAC256(secret);
        return JWT.create().withClaim("username",username).withExpiresAt(date).sign(algorithm);
    }
    /**
     * 根据request中的token获取用户账号
     *
     * @param request
     * @return
     * @throws ApiException
     */
    public static String getUserNameByToken(HttpServletRequest request) throws ApiException {
        String accessToken = request.getHeader(USER_LOGIN_TOKEN);
        String username = getUsername(accessToken);
        if (StringUtils.isEmpty(username)) {
            throw new ApiException("未获取到用户");
        }
        return username;
    }
    /**
     * md5加密
     * @param token
     * @return
     */
    public static String md5Encode(String token){
        return DigestUtil.md5Hex(token);
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/PageUtil.java
对比新文件
@@ -0,0 +1,24 @@
package com.gkhy.assess.common.utils;
import com.github.pagehelper.PageHelper;
import com.gkhy.assess.common.domain.PageDomain;
import com.gkhy.assess.common.domain.TableSupport;
public class PageUtil extends PageHelper{
    public static void startPage(){
        PageDomain pageDomain= TableSupport.buildPageRequest();
        Integer pageNum = pageDomain.getPageNum();
        Integer pageSize=pageDomain.getPageSize();
        String orderby=SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
        PageHelper.startPage(pageNum,pageSize,orderby).setReasonable(pageDomain.getReasonable());
    }
    /**
     * 清理分页的线程变量
     */
    public static void clearPage()
    {
        PageHelper.clearPage();
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/RedisUtils.java
对比新文件
@@ -0,0 +1,780 @@
package com.gkhy.assess.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.connection.RedisStringCommands;
import org.springframework.data.redis.connection.ReturnType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.types.Expiration;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.TimeUnit;
@Component
public class RedisUtils<T> {
    /**
     * 注入redisTemplate bean
     */
    @Autowired
    private RedisTemplate redisTemplate;
    @Value("${spring.application.name}")
    public String prefixRedisName;
    @Value("${spring.profiles.active}")
    public String activeName;
    private static final Long RELEASE_SUCCESS = 1L;
    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    // 当前设置 过期时间单位, EX = seconds; PX = milliseconds
    private static final String SET_WITH_EXPIRE_TIME = "EX";
    // if get(key) == value return del(key)
    private static final String RELEASE_LOCK_SCRIPT = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
    /**
     * 删除指定前缀的key
     * @param pattern
     */
    public void delByScan(String pattern) {
        RedisCallback<Set<String>> redisCallback = connection -> {
            Set<String> keySet = new HashSet<>();
            ScanOptions.ScanOptionsBuilder scanOptionsBuilder = ScanOptions.scanOptions();
            scanOptionsBuilder.match(generateKey(pattern) + "*");
            //scanOptionsBuilder.count(100);
            ScanOptions scanOptions = scanOptionsBuilder.build();
            Cursor<byte[]> cursor = connection.scan(scanOptions);
            int count = 0;
            while (cursor.hasNext()) {
                keySet.add(RedisSerializer.string().deserialize(cursor.next()));
                count++;
            }
            return keySet;
        };
        Set<String> keySet = (Set<String>) redisTemplate.execute(redisCallback);
        Iterator<String> it = keySet.iterator();
        while (it.hasNext()) {
            redisTemplate.delete(it.next());
        }
    }
    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据key获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection<String>) CollectionUtils.arrayToList(key));
            }
        }
    }
    // ============================String(字符串)=============================
    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }
    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间,指定时间单位
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time, TimeUnit timeUnit) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, timeUnit);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time 设置失效时间   s
     * @return true成功 false 失败
     */
    public boolean setNotChangeExpire(String key, Object value,long time) {
        try {
            Long expire=redisTemplate.getExpire(key,TimeUnit.SECONDS);
            if(expire==null ||expire<=0){
                expire=time;
            }
            redisTemplate.opsForValue().set(key, value, expire, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }
    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    // ================================Hash(哈希)=================================
    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }
    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map<Object, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map<Object, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }
    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }
    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }
    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, double by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }
    // ============================Set(集合)=============================
    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    // ===============================List(列表)=================================
    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     * @return
     */
    public List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list从左边放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lLSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().leftPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lLSet(String key, Object value) {
        try {
            redisTemplate.opsForList().leftPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /**
     * 生成统一的前缀key
     * @param subKey
     * @return
     */
    public String generateKey(String subKey){
        if ("pro".equals(activeName)) {
            return generateNoPrefixKey(subKey);
        }
        return activeName + ":" + prefixRedisName+":"+subKey;
    }
    /**
     * 生成小程序token的前缀key
     * @param subKey
     * @return
     */
    public String generateNoPrefixKey(String subKey){
        return prefixRedisName+":"+subKey;
    }
    /**
     * 加锁直接使用set命令同时设置唯一id和过期时间
     * @param lockKey
     * @param clientId
     * @param seconds
     * @return
     */
//    public Boolean tryLock(String lockKey,String clientId,int seconds){
//        try{
//            RedisCallback<Boolean> callback =(redisConnection) -> {
//                RedisSerializer valueSerializer=redisTemplate.getValueSerializer();
//                RedisSerializer keySerializer=redisTemplate.getKeySerializer();
//                Object result= redisConnection.set(keySerializer.serialize(lockKey),
//                        keySerializer.serialize(lockKey),
//                        Expiration.seconds(seconds),
//                        RedisStringCommands.SetOption.SET_IF_ABSENT
//                        );
//                System.out.println(result+"-"+lockKey+"*********************");
//                return (Boolean) result;
//            };
//            Boolean result = (Boolean) redisTemplate.execute(callback);
//            return result;
//        }catch (Exception e) {
//            logger.error("set redis occured an exception", e);
//        }
//        return false;
//    }
    public Boolean tryLock(String lockKey,String clientId,int seconds) {
        RedisCallback<Boolean> callback = connection -> connection.set(lockKey.getBytes(StandardCharsets.UTF_8),
                clientId.getBytes(StandardCharsets.UTF_8), Expiration.seconds(seconds),
                RedisStringCommands.SetOption.SET_IF_ABSENT);
        Object obj=redisTemplate.execute(callback);
        return (Boolean) obj;
    }
    /**
     *释放锁
     * 利用redis的lua脚本保证两个命令的原子性执行
     * @param lockKey
     * @param clientId
     * @return
     */
    public Boolean releaseLock(String lockKey,String clientId){
        RedisCallback<Long> callback =(redisConnection) -> {
            byte[][] keysAndArgs = new byte[2][];
            keysAndArgs[0] = lockKey.getBytes(Charset.forName("UTF-8"));
            keysAndArgs[1] = clientId.getBytes(Charset.forName("UTF-8"));
            Long result = (Long)redisConnection.scriptingCommands().eval(RELEASE_LOCK_SCRIPT.getBytes(StandardCharsets.UTF_8), ReturnType.INTEGER,1,keysAndArgs);
            return result;
        };
        Long result= (Long) redisTemplate.execute(callback);
        if(result!=null&&result==1){
            return true;
        }
        return false;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/RequestUtil.java
对比新文件
@@ -0,0 +1,46 @@
package com.gkhy.assess.common.utils;
import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
 * 请求工具类
 */
public class RequestUtil {
    /**
     * 获取请求真实IP地址
     */
    public static String getRequestIp(HttpServletRequest request) {
        //通过HTTP代理服务器转发时添加
        String ipAddress = request.getHeader("x-forwarded-for");
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
            ipAddress = request.getRemoteAddr();
            // 从本地访问时根据网卡取本机配置的IP
            if (ipAddress.equals("127.0.0.1") || ipAddress.equals("0:0:0:0:0:0:0:1")) {
                InetAddress inetAddress = null;
                try {
                    inetAddress = InetAddress.getLocalHost();
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                }
                ipAddress = inetAddress.getHostAddress();
            }
        }
        // 通过多个代理转发的情况,第一个IP为客户端真实IP,多个IP会按照','分割
        if (ipAddress != null && ipAddress.length() > 15) {
            if (ipAddress.indexOf(",") > 0) {
                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
            }
        }
        return ipAddress;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/ServletUtil.java
对比新文件
@@ -0,0 +1,148 @@
package com.gkhy.assess.common.utils;
import cn.hutool.core.convert.Convert;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
/**
 * 客户端工具类
 *
 */
public class ServletUtil
{
    /**
     * 定义移动端请求的所有可能类型
     */
    private final static String[] agent = { "Android", "iPhone", "iPod", "iPad", "Windows Phone", "MQQBrowser" };
    /**
     * 获取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);
    }
    /**
     * 获取request
     */
    public static HttpServletRequest getRequest()
    {
        return getRequestAttributes().getRequest();
    }
    /**
     * 获取response
     */
    public static HttpServletResponse getResponse()
    {
        return getRequestAttributes().getResponse();
    }
    /**
     * 获取session
     */
    public static HttpSession getSession()
    {
        return getRequest().getSession();
    }
    public static ServletRequestAttributes getRequestAttributes()
    {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }
    /**
     * 将字符串渲染到客户端
     *
     * @param response 渲染对象
     * @param string 待渲染的字符串
     * @return null
     */
    public static String renderString(HttpServletResponse response, String string)
    {
        try
        {
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 判断User-Agent 是不是来自于手机
     */
    public static boolean checkAgentIsMobile(String ua)
    {
        boolean flag = false;
        if (!ua.contains("Windows NT") || (ua.contains("Windows NT") && ua.contains("compatible; MSIE 9.0;")))
        {
            // 排除 苹果桌面系统
            if (!ua.contains("Windows NT") && !ua.contains("Macintosh"))
            {
                for (String item : agent)
                {
                    if (ua.contains(item))
                    {
                        flag = true;
                        break;
                    }
                }
            }
        }
        return flag;
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/SpringContextUtils.java
对比新文件
@@ -0,0 +1,91 @@
package com.gkhy.assess.common.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @Description: spring上下文工具类
 * @author: jeecg-boot
 */
@Component
public class SpringContextUtils implements ApplicationContextAware {
    /**
     * 上下文对象实例
     */
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }
    /**
     * 获取applicationContext
     *
     * @return
     */
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    /**
      * 获取HttpServletRequest
     */
    public static HttpServletRequest getHttpServletRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }
    /**
     * 获取HttpServletResponse
     */
    public static HttpServletResponse getHttpServletResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }
    public static String getOrigin(){
        HttpServletRequest request = getHttpServletRequest();
        return request.getHeader("Origin");
    }
    /**
     * 通过name获取 Bean.
     *
     * @param name
     * @return
     */
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }
    /**
     * 通过class获取Bean.
     *
     * @param clazz
     * @param       <T>
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }
    /**
     * 通过name,以及Clazz返回指定的Bean
     *
     * @param name
     * @param clazz
     * @param       <T>
     * @return
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/SqlUtil.java
对比新文件
@@ -0,0 +1,73 @@
package com.gkhy.assess.common.utils;
import cn.hutool.core.util.StrUtil;
import com.gkhy.assess.common.exception.UtilException;
import java.util.List;
/**
 * 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_\\ \\,\\.]+";
    /**
     * 限制orderBy最大长度
     */
    private static final int ORDER_BY_MAX_LENGTH = 500;
    /**
     * 检查字符,防止注入绕过
     */
    public static String escapeOrderBySql(String value)
    {
        if (StrUtil.isNotEmpty(value) && !isValidOrderBySql(value))
        {
            throw new UtilException("参数不符合规范,不能进行查询");
        }
        if (StrUtil.length(value) > ORDER_BY_MAX_LENGTH)
        {
            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 (StrUtil.isEmpty(value))
        {
            return;
        }
        List<String> sqlKeywords = StrUtil.split(SQL_REGEX, "\\|");
        for (String sqlKeyword : sqlKeywords)
        {
            if (StrUtil.indexOfIgnoreCase(value, sqlKeyword) > -1)
            {
                throw new UtilException("参数存在SQL注入风险");
            }
        }
    }
}
assess-common/src/main/java/com/gkhy/assess/common/utils/Threads.java
对比新文件
@@ -0,0 +1,34 @@
package com.gkhy.assess.common.utils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
/**
 * 线程相关工具类
 */
public class Threads {
    private static final Logger logger = LoggerFactory.getLogger(Threads.class);
    public static void printException(Runnable r,Throwable t){
        if(t==null && r instanceof Future<?>){
            try {
                Future<?> future= (Future<?>) r;
                if(future.isDone()) {
                    future.get();
                }
            } catch (CancellationException e){
                t=e;
            } catch (ExecutionException e) {
                t=e.getCause();
            }catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        if(t!=null){
            logger.error(t.getMessage(),t);
        }
    }
}
assess-common/src/main/java/com/gkhy/assess/common/validate/AgencyGroup.java
对比新文件
@@ -0,0 +1,7 @@
package com.gkhy.assess.common.validate;
/**
 * 机构校验分组
 */
public interface AgencyGroup {
}
assess-common/src/main/java/com/gkhy/assess/common/validate/ExpertGroup.java
对比新文件
@@ -0,0 +1,7 @@
package com.gkhy.assess.common.validate;
/**
 * 专家校验分组
 */
public interface ExpertGroup {
}
assess-framework/pom.xml
对比新文件
@@ -0,0 +1,35 @@
<?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.gkhy.assess</groupId>
        <artifactId>smart_assess</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>assess-framework</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>
        <dependency>
            <groupId>com.gkhy.assess</groupId>
            <artifactId>assess-system</artifactId>
        </dependency>
        <!-- SpringBoot Web容器 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
</project>
assess-framework/src/main/java/com/gkhy/assess/framework/config/ApplicationConfig.java
对比新文件
@@ -0,0 +1,51 @@
package com.gkhy.assess.framework.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import java.util.TimeZone;
/**
 * 程序注解配置
 *
 * @author ruoyi
 */
@Configuration
// 表示通过aop框架暴露该代理对象,AopContext能够访问
@EnableAspectJAutoProxy(exposeProxy = true)
// 指定要扫描的Mapper类的包的路径
@MapperScan("com.gkhy.**.mapper")
public class ApplicationConfig
{
    /**
     * 时区配置
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization()
    {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
    }
    @Bean
    public CorsFilter corsFilter() {
        final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration corsConfiguration = new CorsConfiguration();
        //是否允许请求带有验证信息
        corsConfiguration.setAllowCredentials(true);
        // 允许访问的客户端域名
        corsConfiguration.addAllowedOriginPattern("*");
        // 允许服务端访问的客户端请求头
        corsConfiguration.addAllowedHeader("*");
        // 允许访问的方法名,GET POST等
        corsConfiguration.addAllowedMethod("*");
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java
对比新文件
@@ -0,0 +1,103 @@
package com.gkhy.assess.framework.config;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
import com.alibaba.druid.util.Utils;
import com.gkhy.assess.common.enums.DataSourceTypeEnum;
import com.gkhy.assess.framework.config.properties.DruidProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.servlet.*;
import javax.sql.DataSource;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class DruidConfig {
    @Bean(name = "masterDataSource")
    @ConfigurationProperties("spring.datasource.druid.master")
    public DataSource masterDataSource(DruidProperties druidProperties){
        DruidDataSource dataSource= DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties("spring.datasource.druid.slave")
    @ConditionalOnProperty(prefix = "spring.datasource.druid.slave",name="enabled",havingValue = "true")
    public DataSource slaveDataSource(DruidProperties druidProperties){
        DruidDataSource dataSource=DruidDataSourceBuilder.create().build();
        return druidProperties.dataSource(dataSource);
    }
    @Bean(name="dynamicDataSource")
    @Primary
    public DynamicDataSource dataSource(DataSource masterDataSource){
        Map<Object,Object> targetDataSources=new HashMap<>();
        targetDataSources.put(DataSourceTypeEnum.MASTER.name(),masterDataSource);
        setDataSource(targetDataSources, DataSourceTypeEnum.SLAVE.name(),"slaveDataSource");
        return new DynamicDataSource(masterDataSource,targetDataSources);
    }
    /**
     * 设置数据源
     * @param targetDataSource 备选数据源集合
     * @param sourceName   数据源名称
     * @param beanName    bean名称
     */
    public void setDataSource(Map<Object,Object>targetDataSource,String sourceName,String beanName){
        try {
            DataSource dataSource = SpringUtil.getBean(beanName);
            targetDataSource.put(sourceName, dataSource);
        }catch (Exception e){
        }
    }
    /**
     * 去除监控页面底部的广告
     * @param properties
     * @return
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    @ConditionalOnProperty(name="spring.datasource.druid.statViewServlet.enabled",havingValue = "true")
    public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties){
        DruidStatProperties.StatViewServlet config=properties.getStatViewServlet();
        String pattern=config.getUrlPattern()!=null?config.getUrlPattern():"/druid/*";
        String commonJsPattern=pattern.replaceAll("\\*","js/common.js");
        final String filePath="support/http/resources/js/common.js";
        Filter filter=new Filter() {
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                filterChain.doFilter(servletRequest,servletResponse);
                // 重置缓冲区,响应头不会被重置
                servletResponse.resetBuffer();
                // 获取common.js
                String text= Utils.readFromResource(filePath);
                text=text.replaceAll("<a.*?banner\"></a><br/>","");
                text=text.replaceAll("powered.*?shrek.wang</a>","");
                servletResponse.getWriter().write(text);
            }
        };
        FilterRegistrationBean registrationBean=new FilterRegistrationBean<>();
        registrationBean.setFilter(filter);
        registrationBean.addUrlPatterns(commonJsPattern);
        return registrationBean;
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/config/DynamicDataSource.java
对比新文件
@@ -0,0 +1,28 @@
package com.gkhy.assess.framework.config;
import com.gkhy.assess.common.config.DynamicDataSourceContextHolder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import javax.sql.DataSource;
import java.util.Map;
/**
 * 动态数据源
 *
 * @author ruoyi
 */
public class DynamicDataSource extends AbstractRoutingDataSource
{
    public DynamicDataSource(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources)
    {
        super.setDefaultTargetDataSource(defaultTargetDataSource);
        super.setTargetDataSources(targetDataSources);
        super.afterPropertiesSet();
    }
    @Override
    protected Object determineCurrentLookupKey()
    {
        return DynamicDataSourceContextHolder.getDataSourceType();
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/config/MyWebMvcConfig.java
对比新文件
@@ -0,0 +1,38 @@
package com.gkhy.assess.framework.config;
import com.gkhy.assess.framework.interceptor.LogInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.File;
@Configuration
public class MyWebMvcConfig implements WebMvcConfigurer {
    @Value("${image.root_path}")
    private String uploadRootPath;
    @Autowired
    private LogInterceptor logInterceptor;
    /**
     * 配置图片访问路径
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        String systemDir=System.getProperty("user.dir");
        registry.addResourceHandler("/api/assess_file/**").addResourceLocations("file:"+systemDir+ File.separator+uploadRootPath+File.separator);
      }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(logInterceptor)
                .addPathPatterns("/**");
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/config/RedisConfig.java
对比新文件
@@ -0,0 +1,12 @@
package com.gkhy.assess.framework.config;
import com.gkhy.assess.common.config.BaseRedisConfig;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;
@EnableCaching
@Configuration
public class RedisConfig extends BaseRedisConfig {
}
assess-framework/src/main/java/com/gkhy/assess/framework/config/properties/DruidProperties.java
对比新文件
@@ -0,0 +1,89 @@
package com.gkhy.assess.framework.config.properties;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
 * druid 配置属性
 *
 * @author ruoyi
 */
@Configuration
public class DruidProperties
{
    @Value("${spring.datasource.druid.initialSize}")
    private int initialSize;
    @Value("${spring.datasource.druid.minIdle}")
    private int minIdle;
    @Value("${spring.datasource.druid.maxActive}")
    private int maxActive;
    @Value("${spring.datasource.druid.maxWait}")
    private int maxWait;
    @Value("${spring.datasource.druid.connectTimeout}")
    private int connectTimeout;
    @Value("${spring.datasource.druid.socketTimeout}")
    private int socketTimeout;
    @Value("${spring.datasource.druid.timeBetweenEvictionRunsMillis}")
    private int timeBetweenEvictionRunsMillis;
    @Value("${spring.datasource.druid.minEvictableIdleTimeMillis}")
    private int minEvictableIdleTimeMillis;
    @Value("${spring.datasource.druid.maxEvictableIdleTimeMillis}")
    private int maxEvictableIdleTimeMillis;
    @Value("${spring.datasource.druid.validationQuery}")
    private String validationQuery;
    @Value("${spring.datasource.druid.testWhileIdle}")
    private boolean testWhileIdle;
    @Value("${spring.datasource.druid.testOnBorrow}")
    private boolean testOnBorrow;
    @Value("${spring.datasource.druid.testOnReturn}")
    private boolean testOnReturn;
    public DruidDataSource dataSource(DruidDataSource datasource)
    {
        /** 配置初始化大小、最小、最大 */
        datasource.setInitialSize(initialSize);
        datasource.setMaxActive(maxActive);
        datasource.setMinIdle(minIdle);
        /** 配置获取连接等待超时的时间 */
        datasource.setMaxWait(maxWait);
        /** 配置驱动连接超时时间,检测数据库建立连接的超时时间,单位是毫秒 */
        datasource.setConnectTimeout(connectTimeout);
        /** 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒 */
        datasource.setSocketTimeout(socketTimeout);
        /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */
        datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
        /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */
        datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
        datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
        /**
         * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
         */
        datasource.setValidationQuery(validationQuery);
        /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */
        datasource.setTestWhileIdle(testWhileIdle);
        /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
        datasource.setTestOnBorrow(testOnBorrow);
        /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */
        datasource.setTestOnReturn(testOnReturn);
        return datasource;
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/exception/GlobalExceptionHandler.java
对比新文件
@@ -0,0 +1,110 @@
package com.gkhy.assess.framework.exception;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.common.exception.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
/**
 * 全局异常处理类
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @Autowired
    HttpServletRequest request;
    @ExceptionHandler(value = ApiException.class)
    public CommonResult handle(ApiException e){
        writeExceptionLogFile(e);
        if(e.getErrorCode()!=null){
            return CommonResult.failed(e.getErrorCode());
        }
        return CommonResult.failed(e.getMessage());
    }
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResult handleValidException(MethodArgumentNotValidException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField()+fieldError.getDefaultMessage();
            }
        }
        writeExceptionLogFile(e);
        return CommonResult.validateFailed(message);
    }
    @ExceptionHandler(value = BindException.class)
    public CommonResult handleValidException(BindException e) {
        BindingResult bindingResult = e.getBindingResult();
        String message = null;
        if (bindingResult.hasErrors()) {
            FieldError fieldError = bindingResult.getFieldError();
            if (fieldError != null) {
                message = fieldError.getField()+fieldError.getDefaultMessage();
            }
        }
        writeExceptionLogFile(e);
        return CommonResult.validateFailed(message);
    }
    @ExceptionHandler(SQLException.class)
    public CommonResult sqlExceptionHandler(Exception ex) {
        writeExceptionLogFile(ex);
        return CommonResult.failed( "执行sql异常");
    }
    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    public CommonResult handleRuntimeException(RuntimeException ex, HttpServletRequest request)
    {
        writeExceptionLogFile(ex);
        return CommonResult.failed(ex.getMessage());
    }
    /**
     * 500 其他服务器异常
     */
    @ExceptionHandler(Exception.class)
    public CommonResult otherExceptionHandler(Exception ex) {
        String message = !StringUtils.isEmpty(ex.getMessage()) ? ex.getMessage() : ex.toString();
        if(StringUtils.isNotBlank(message)&&message.contains("java.sql")){
            message="执行sql异常";
        }
        writeExceptionLogFile(ex);
        return CommonResult.failed(message);
    }
    private void writeExceptionLogFile(Exception ex) {
        String url="";
        if (request!=null) {
            url=request.getRequestURI();
        }
        log.error("error={}",ex);
        log.error(ex.getMessage()+",url={}",url);
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java
对比新文件
@@ -0,0 +1,38 @@
package com.gkhy.assess.framework.interceptor;
import cn.hutool.extra.servlet.ServletUtil;
import com.gkhy.assess.system.utils.ShiroUtils;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.UUID;
/**
 * @ClassName LogInterceptor
 * @Description TODO
 * @Date 2021/7/5 14:56
 **/
@Component
public class LogInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String requestId = UUID.randomUUID().toString();
        String ip = ServletUtil.getClientIP(request,null);
        String url=request.getRequestURI();
        MDC.put("requestId", requestId);
        MDC.put("clientIP", ip);
        MDC.put("url", url);
        String userId= String.valueOf(ShiroUtils.getUserId());
        MDC.put("userId", userId);
        return true;
    }
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        MDC.clear();
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/JwtToken.java
对比新文件
@@ -0,0 +1,22 @@
package com.gkhy.assess.framework.shiro;
import org.apache.shiro.authc.UsernamePasswordToken;
public class JwtToken extends UsernamePasswordToken {
    private String jwtToken;
    public JwtToken(String jwtToken) {
        this.jwtToken = jwtToken;
    }
    @Override
    public Object getPrincipal() {
        return this.jwtToken;
    }
    @Override
    public Object getCredentials() {
        return this.jwtToken;
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java
对比新文件
@@ -0,0 +1,199 @@
package com.gkhy.assess.framework.shiro;
import com.gkhy.assess.framework.shiro.filter.JwtFilter;
import com.gkhy.assess.framework.shiro.realm.UserRealm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;
import org.apache.shiro.mgt.DefaultSubjectDAO;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.config.DefaultShiroFilterChainDefinition;
import org.apache.shiro.spring.web.config.ShiroFilterChainDefinition;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.crazycake.shiro.IRedisManager;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisClusterManager;
import org.crazycake.shiro.RedisManager;
import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import javax.annotation.Resource;
import javax.servlet.Filter;
import java.util.HashSet;
import java.util.Set;
@Configuration
@Slf4j
public class ShiroConfig {
    @Resource
    private LettuceConnectionFactory lettuceConnectionFactory;
    @Bean
    public JwtFilter jwtFilter() {
        //过滤器如果加了@Compoent就没必要用这个方法了
        return new JwtFilter();
    }
    @Bean
    public FilterRegistrationBean<Filter> registration(JwtFilter filter) {
        FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<Filter>(new JwtFilter());
        registration.setEnabled(true);
        return registration;
    }
    @Bean
    public ShiroFilterChainDefinition shiroFilterChainDefinition(){
        DefaultShiroFilterChainDefinition chain=new DefaultShiroFilterChainDefinition();
        //放行Swagger2页面
        chain.addPathDefinition("/swagger-ui.html","anon");
        chain.addPathDefinition("/swagger/**","anon");
        chain.addPathDefinition("/webjars/**", "anon");
        chain.addPathDefinition("/swagger-resources/**","anon");
        chain.addPathDefinition("/account/login","anon");
      //  chain.addPathDefinition("/api/account/login","anon");
        chain.addPathDefinition("/logout", "logout");
        chain.addPathDefinition("/system/notice/noticeList","anon");
        chain.addPathDefinition("/system/notice/getNoticeById","anon");
        chain.addPathDefinition("/system/law/lawList","anon");
        chain.addPathDefinition("/system/law/getLawById","anon");
        chain.addPathDefinition("/system/agency/agencyList","anon");
        chain.addPathDefinition("/system/agency/getAgencyById","anon");
        chain.addPathDefinition("/system/user/agencyRegister","anon");
        //除了以上的请求外,其它请求都需要登录
        chain.addPathDefinition("/**", "jwtFilter,authc"); // 需登录才能访问
     //   chain.addPathDefinition("/**", "anon"); // 需登录才能访问
       return chain;
    }
    @Bean
    public DefaultWebSecurityManager securityManager(UserRealm realm){
        DefaultWebSecurityManager securityManager=new DefaultWebSecurityManager();
        securityManager.setRealm(realm);
        // 关闭shiro自带的session
        DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
        //禁用session, 不保存用户登录状态。保证每次请求都重新认证
        DefaultSessionStorageEvaluator defaultSessionStorageEvaluator=new DefaultSessionStorageEvaluator();
        defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
        subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
        securityManager.setSubjectDAO(subjectDAO);
        //自定义缓存实现,使用redis
        securityManager.setCacheManager(redisCacheManager());
        return securityManager;
    }
    /**
     * 下面的代码是添加注解支持
     * @return
     */
    @Bean
    @DependsOn("lifecycleBeanPostProcessor")
    public static DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
        defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
        /**
         * setUsePrefix(false)用于解决一个奇怪的bug。在引入spring aop的情况下。
         * 在@Controller注解的类的方法中加入@RequiresRole注解,会导致该方法无法映射请求,导致返回404。
         * 加入这项配置能解决这个bug
         */
        defaultAdvisorAutoProxyCreator.setUsePrefix(true);
        defaultAdvisorAutoProxyCreator.setAdvisorBeanNamePrefix("_no_advisor");
        return defaultAdvisorAutoProxyCreator;
    }
    @Bean
    public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
        advisor.setSecurityManager(securityManager);
        return advisor;
    }
    /**
     * cacheManager 缓存 redis实现
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    public RedisCacheManager redisCacheManager() {
        log.info("===============(1)创建缓存管理器RedisCacheManager");
        RedisCacheManager redisCacheManager = new RedisCacheManager();
        redisCacheManager.setRedisManager(redisManager());
        //redis中针对不同用户缓存(此处的id需要对应user实体中的id字段,用于唯一标识)
        redisCacheManager.setPrincipalIdFieldName("id");
        //用户权限信息缓存时间
        redisCacheManager.setExpire(200000);
        return redisCacheManager;
    }
    /**
     * 来源jeecg-boot项目
     * 配置shiro redisManager
     * 使用的是shiro-redis开源插件
     *
     * @return
     */
    @Bean
    public IRedisManager redisManager() {
        log.info("===============(2)创建RedisManager,连接Redis..");
        IRedisManager manager;
        // redis 单机支持,在集群为空,或者集群无机器时候使用 add by jzyadmin@163.com
        if (lettuceConnectionFactory.getClusterConfiguration() == null || lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().isEmpty()) {
            RedisManager redisManager = new RedisManager();
            redisManager.setHost(lettuceConnectionFactory.getHostName() + ":" + lettuceConnectionFactory.getPort());
            //(lettuceConnectionFactory.getPort());
            redisManager.setDatabase(lettuceConnectionFactory.getDatabase());
            redisManager.setTimeout(0);
            if (!StringUtils.isEmpty(lettuceConnectionFactory.getPassword())) {
                redisManager.setPassword(lettuceConnectionFactory.getPassword());
            }
            manager = redisManager;
        }else{
            // redis集群支持,优先使用集群配置
            RedisClusterManager redisManager = new RedisClusterManager();
            Set<HostAndPort> portSet = new HashSet<>();
            lettuceConnectionFactory.getClusterConfiguration().getClusterNodes().forEach(node -> portSet.add(new HostAndPort(node.getHost() , node.getPort())));
            //update-begin--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
            if (StringUtils.isNotEmpty(lettuceConnectionFactory.getPassword())) {
                JedisCluster jedisCluster = new JedisCluster(portSet, 2000, 2000, 5,
                        lettuceConnectionFactory.getPassword(), new GenericObjectPoolConfig());
                redisManager.setPassword(lettuceConnectionFactory.getPassword());
                redisManager.setJedisCluster(jedisCluster);
            } else {
                JedisCluster jedisCluster = new JedisCluster(portSet);
                redisManager.setJedisCluster(jedisCluster);
            }
            //update-end--Author:scott Date:20210531 for:修改集群模式下未设置redis密码的bug issues/I3QNIC
            manager = redisManager;
        }
        return manager;
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/filter/JwtFilter.java
对比新文件
@@ -0,0 +1,137 @@
package com.gkhy.assess.framework.shiro.filter;
import com.alibaba.fastjson.JSONObject;
import com.gkhy.assess.common.api.CommonResult;
import com.gkhy.assess.common.api.ResultCode;
import com.gkhy.assess.common.utils.JwtTokenUtil;
import com.gkhy.assess.framework.shiro.JwtToken;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@Slf4j
public class JwtFilter extends BasicHttpAuthenticationFilter {
    /**
     * 默认开启跨域设置(使用单体)
     * 微服务情况下,此属性设置为false
     */
    private boolean allowOrigin = true;
    public JwtFilter(){}
    public JwtFilter(boolean allowOrigin){
        this.allowOrigin=allowOrigin;
    }
    /**
     * 前置拦截处理
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
        //servlet请求与响应的转换
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        if(allowOrigin){
            this.fillCorsHeader(WebUtils.toHttp(request), WebUtils.toHttp(response));
        }
        //跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态
        if(httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())){
            httpServletResponse.setStatus(HttpStatus.OK.value());
            return false;
        }
        return super.preHandle(request, response);
    }
    /**
     * 过滤器拦截请求的入口方法,所有请求都会进入该方法
     * 返回true则允许访问
     * @param request
     * @param response
     * @param mappedValue
     * @return
     */
    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        try{
            //检测header里的JWT Token内容是否正确,尝试使用token进行登录
            this.executeLogin(request,response);
            return true;
        } catch (Exception e){ //未找到token
            log.error(e.getMessage());
        }
        return false;
    }
    /**
     * 身份验证,检查JWT token是否合法
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String jwtToken = httpServletRequest.getHeader(JwtTokenUtil.USER_LOGIN_TOKEN);
        JwtToken token=new JwtToken(jwtToken);
        Subject subject = getSubject(request,response);
        subject.login(token);
        return true;
    }
    /**
     * isAccessAllowed()方法返回false,会进入该方法,表示拒绝访问
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        httpServletResponse.setStatus(HttpStatus.OK.value());
        PrintWriter writer = httpServletResponse.getWriter();
        writer.write(JSONObject.toJSONString(CommonResult.failed(ResultCode.UNAUTHORIZED)));
        return false;
    }
    //跨域请求的解决方案之一
    protected void fillCorsHeader(HttpServletRequest request, HttpServletResponse response){
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, request.getHeader(HttpHeaders.ORIGIN));
        // 允许客户端请求方法
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,OPTIONS,HEAD,PUT,DELETE");
        // 允许客户端提交的Header
        String requestHeaders = request.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS);
        if (StringUtils.isNotEmpty(requestHeaders)) {
            response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders);
        }
        // 允许客户端携带凭证信息(是否允许发送Cookie)
        response.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/realm/UserRealm.java
对比新文件
@@ -0,0 +1,102 @@
package com.gkhy.assess.framework.shiro.realm;
import com.gkhy.assess.common.utils.RequestUtil;
import com.gkhy.assess.common.utils.SpringContextUtils;
import com.gkhy.assess.framework.shiro.JwtToken;
import com.gkhy.assess.framework.shiro.service.SysLoginService;
import com.gkhy.assess.system.domain.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.SimplePrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.HashSet;
import java.util.Set;
@Slf4j
@Component
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private SysLoginService sysLoginService;
    /**
     * 授权
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        SysUser sysUser = (SysUser) principalCollection.getPrimaryPrincipal();
        Set<String> roles=new HashSet<>();
        Set<String> menus=new HashSet<>();
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.addRole("admin");
        info.addStringPermission("*:*:*");
        return info;
    }
    /**
     * 认证
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        SysUser sysUser=null;
        if(authenticationToken instanceof JwtToken){
            String token= (String) authenticationToken.getCredentials();
            if(token==null){
                HttpServletRequest req = SpringContextUtils.getHttpServletRequest();
                log.info("————————身份认证失败——————————IP地址:  "+ RequestUtil.getRequestIp(req) +",URL:"+req.getRequestURI());
                throw new AuthenticationException("token为空!");
            }
            sysUser=sysLoginService.validJwtToken(token);
            if(sysUser!=null){
                return new SimpleAuthenticationInfo(sysUser,token,this.getName());
            }
        }else{
            UsernamePasswordToken upToken = (UsernamePasswordToken) authenticationToken;
            String username = upToken.getUsername();
            String password=new String(upToken.getPassword());
            sysUser=sysLoginService.login(username,password);
            if(sysUser!=null){
                return new SimpleAuthenticationInfo(sysUser,password,this.getName());
            }
        }
        return null;
    }
    /**
     * 清理指定用户授权信息缓存
     */
    public void clearCachedAuthorizationInfo(Object principal)
    {
        SimplePrincipalCollection principals = new SimplePrincipalCollection(principal, getName());
        this.clearCachedAuthorizationInfo(principals);
    }
    /**
     * 清理所有用户授权信息缓存
     */
    public void clearAllCachedAuthorizationInfo()
    {
        Cache<Object, AuthorizationInfo> cache = getAuthorizationCache();
        if (cache != null)
        {
            for (Object key : cache.keys())
            {
                cache.remove(key);
            }
        }
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysLoginService.java
对比新文件
@@ -0,0 +1,99 @@
package com.gkhy.assess.framework.shiro.service;
import com.gkhy.assess.common.constant.CacheConstant;
import com.gkhy.assess.common.enums.UserStatusEnum;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.JwtTokenUtil;
import com.gkhy.assess.common.utils.RedisUtils;
import com.gkhy.assess.system.domain.SysUser;
import com.gkhy.assess.system.service.SysUserService;
import com.gkhy.assess.system.utils.ShiroUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
@Component
public class SysLoginService  {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysPasswordService passwordService;
    @Autowired
    private RedisUtils redisUtils;
    public SysUser login(String username, String password) {
        SysUser sysUser=sysUserService.getUserByUsernamePhone(username);
        validUser(sysUser);
        passwordService.validate(sysUser,password);
        recordLoginInfo(sysUser.getId());
        return sysUser;
    }
    public void validUser(SysUser sysUser){
        if(sysUser==null) {
            throw new ApiException("用户不存在");
        }
        if(UserStatusEnum.DELETED.getCode().equals(sysUser.getDelFlag())){
            throw new ApiException("用户已被删除");
        }
        if(UserStatusEnum.DISABLE.getCode().equals(sysUser.getStatus())){
            throw new ApiException("用户已被停用");
        }
    }
    public SysUser validJwtToken(String jwtToken){
        String username= JwtTokenUtil.getUsername(jwtToken);
        if(StringUtils.isEmpty(username)){
            throw new AuthenticationException("token非法无效!");
        }
        SysUser sysUser=sysUserService.getUserByUsernamePhone(username);
        validUser(sysUser);
        if(!jwtTokenRefresh(jwtToken,username,sysUser.getPassword())){
            throw new AuthenticationException("Token失效,请重新登录!");
        }
     //   setRolePermission(sysUser);
        return sysUser;
    }
    /**
     * JWTToken刷新生命周期 (实现: 用户在线操作不掉线功能)
     * 1、登录成功后将用户的JWT生成的Token作为k、v存储到cache缓存里面(这时候k、v值一样),缓存有效期设置为Jwt有效时间的2倍
     * 2、当该用户再次请求时,通过JWTFilter层层校验之后会进入到doGetAuthenticationInfo进行身份验证
     * 3、当该用户这次请求jwt生成的token值已经超时,但该token对应cache中的k还是存在,则表示该用户一直在操作只是JWT的token失效了,程序会给token对应的k映射的v值重新生成JWTToken并覆盖v值,该缓存生命周期重新计算
     * 4、当该用户这次请求jwt在生成的token值已经超时,并在cache中不存在对应的k,则表示该用户账户空闲超时,返回用户信息已失效,请重新登录。
     * 注意: 前端请求Header中设置Authorization保持不变,校验有效性以缓存中的token为准。
     *       用户过期时间 = Jwt有效时间 * 2。
     *
     * @param username
     * @param passWord
     * @return
     */
    public boolean jwtTokenRefresh(String jwtToken,String username,String passWord){
        String key=redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+":"+JwtTokenUtil.md5Encode(jwtToken));
        String cacheToken= (String) redisUtils.get(key);
        if(StringUtils.isNotEmpty(cacheToken)){
            // 校验token有效性
            if(!JwtTokenUtil.verify(cacheToken,username,passWord)){
                String newToken=JwtTokenUtil.sign(username,passWord);
                // 设置超时时间
                redisUtils.set(key,newToken);
                redisUtils.expire(key,JwtTokenUtil.EXPIRATION*2/1000);
            }
            return true;
        }
        return false;
    }
    public void recordLoginInfo(Long userId){
        SysUser user=new SysUser();
        user.setId(userId);
        user.setLoginIp(ShiroUtils.getIp());
        user.setLoginDate(LocalDateTime.now());
        sysUserService.updateById(user);
    }
}
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/service/SysPasswordService.java
对比新文件
@@ -0,0 +1,52 @@
package com.gkhy.assess.framework.shiro.service;
import com.gkhy.assess.common.constant.CacheConstant;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.RedisUtils;
import com.gkhy.assess.system.domain.SysUser;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.concurrent.atomic.AtomicInteger;
@Component
public class SysPasswordService {
    @Autowired
    private RedisUtils redisUtils;
    @Value(value = "${user.password.maxRetryCount:5}")
    private Integer maxRetryCount;
    public void validate(SysUser user, String password){
        String username=user.getUsername();
        String key= redisUtils.generateKey(CacheConstant.SYS_LOGIN_RECORD_CACHE+":"+username);
        AtomicInteger retryCount= (AtomicInteger) redisUtils.get(key);
        if(retryCount==null){
            retryCount=new AtomicInteger(0);
            redisUtils.set(key,retryCount);
        }
        if(retryCount.incrementAndGet()>maxRetryCount){
            throw new ApiException("登录次数已达上限");
        }
        if(!matches(user,password)){
            redisUtils.set(key,retryCount);
            throw new ApiException("登录密码错误");
        }else{
            redisUtils.del(key);
        }
    }
    public boolean matches(SysUser sysUser,String newPassword){
        return sysUser.getPassword().equals(encryptPassword(sysUser.getUsername(),newPassword,sysUser.getSalt()));
    }
    public String encryptPassword(String username,String password,String salt){
        return new Md5Hash(username+password+salt).toHex();
    }
}
assess-system/pom.xml
对比新文件
@@ -0,0 +1,29 @@
<?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.gkhy.assess</groupId>
        <artifactId>smart_assess</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>assess-system</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>
        <dependency>
            <groupId>com.gkhy.assess</groupId>
            <artifactId>assess-common</artifactId>
        </dependency>
    </dependencies>
</project>
assess-system/src/main/java/com/gkhy/assess/system/domain/SysAgency.java
对比新文件
@@ -0,0 +1,150 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.gkhy.assess.common.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
/**
 * <p>
 * 机构表
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:36
 */
@Getter
@Setter
@TableName("sys_agency")
@ApiModel(value = "SysAgency对象", description = "机构表")
@JsonInclude(NON_NULL)
public class SysAgency extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @NotBlank(message = "机构名称不能为空")
    @ApiModelProperty("机构名称")
    @TableField("name")
    private String name;
    @NotBlank(message = "社会信用代码不能为空")
    @ApiModelProperty(value = "社会信用代码",required = true)
    @TableField("credit_code")
    private String creditCode;
    @NotNull(message = "机构属性不能为空")
    @ApiModelProperty(value = "机构属性(0疆内,1疆外,默认0)",required = true)
    @TableField("attribute")
    private Integer attribute;
    @ApiModelProperty("省")
    @TableField("province")
    private String province;
    @NotBlank(message = "市不能为空")
    @ApiModelProperty(value = "市",required = true)
    @TableField("city")
    private String city;
    @NotBlank(message = "区不能为空")
    @ApiModelProperty(value = "区",required = true)
    @TableField("district")
    private String district;
    @NotBlank(message = "经营地址不能为空")
    @ApiModelProperty(value = "经营地址",required = true)
    @TableField("address")
    private String address;
    @ApiModelProperty("机构网址")
    @TableField("web")
    private String web;
    @NotBlank(message = "法定代表人不能为空")
    @ApiModelProperty(value = "法定代表人",required = true)
    @TableField("legal_person")
    private String legalPerson;
    @NotBlank(message = "法人电话不能为空")
    @ApiModelProperty(value = "法人电话",required = true)
    @TableField("legal_phone")
    private String legalPhone;
    @NotBlank(message = "机构负责人不能为空")
    @ApiModelProperty(value = "机构负责人",required = true)
    @TableField("manager")
    private String manager;
    @NotBlank(message = "负责人电话不能为空")
    @ApiModelProperty(value = "负责人电话",required = true)
    @TableField("manager_phone")
    private String managerPhone;
    @NotBlank(message = "资质证书编号不能为空")
    @ApiModelProperty(value = "资质证书编号",required = true)
    @TableField("cert_number")
    private String certNumber;
    @NotBlank(message = "发证日期不能为空")
    @ApiModelProperty(value = "发证日期",required = true)
    @TableField("issue_date")
    private LocalDateTime issueDate;
    @NotBlank(message = "有效日期不能为空")
    @ApiModelProperty(value = "有效日期",required = true)
    @TableField("valid_date")
    private LocalDateTime validDate;
    @NotBlank(message = "固定资产总值不能为空")
    @ApiModelProperty(value = "固定资产总值",required = true)
    @TableField("asset_value")
    private String assetValue;
    @NotBlank(message = "工作场所建筑面积不能为空")
    @ApiModelProperty(value = "工作场所建筑面积",required = true)
    @TableField("work_area")
    private String workArea;
    @NotBlank(message = "档案室面积不能为空")
    @ApiModelProperty(value = "档案室面积",required = true)
    @TableField("archive_area")
    private String archiveArea;
    @NotBlank(message = "注册地址不能为空")
    @ApiModelProperty(value = "注册地址",required = true)
    @TableField("reg_address")
    private String regAddress;
    @NotBlank(message = "业务范围不能为空")
    @ApiModelProperty(value = "业务范围",required = true)
    @TableField("business")
    private String business;
    @NotBlank(message = "机构信息上报表存放路径不能为空")
    @ApiModelProperty(value = "机构信息上报表存放路径",required = true)
    @TableField("report_path")
    private String reportPath;
    @ApiModelProperty("删除标志(0代表存在,1代表删除,默认0)")
    @TableField("del_flag")
    private Integer delFlag;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysAttach.java
对比新文件
@@ -0,0 +1,75 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
/**
 * <p>
 * 系统配置表
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 17:08:49
 */
@Getter
@Setter
@TableName("sys_attach")
@ApiModel(value = "SysAttach对象", description = "系统配置表")
@JsonInclude(NON_NULL)
public class SysAttach implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @NotBlank(message = "文件名称不能为空")
    @ApiModelProperty(value = "文件名称",required = true)
    @TableField("name")
    private String name;
    @NotBlank(message = "文件存放路径不能为空")
    @ApiModelProperty(value = "文件存放路径",required = true)
    @TableField("path")
    private String path;
    @NotBlank(message = "类型不能为空")
    @ApiModelProperty(value = "类型(1社保,2医保,3工资单)",required = true)
    @TableField("type")
    private Integer type;
    @NotBlank(message = "类型不能为空")
    @ApiModelProperty(value = "用户id",required = true)
    @TableField("user_id")
    private Long userId;
    @ApiModelProperty("创建人")
    @TableField("create_by")
    private String createBy;
    @TableField("create_time")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    @TableField("update_by")
    private String updateBy;
    @TableField("update_time")
    private LocalDateTime updateTime;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysConfig.java
对比新文件
@@ -0,0 +1,70 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
 * <p>
 * 系统配置表
 * </p>
 *
 * @author kzy
 * @since 2023-11-13 08:39:55
 */
@Getter
@Setter
@Accessors(chain = true)
@TableName("sys_config")
@ApiModel(value = "SysConfig对象", description = "系统配置表")
public class SysConfig implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("参数名称")
    @TableField("name")
    private String name;
    @ApiModelProperty("参数键名")
    @TableField("config_key")
    private String configKey;
    @ApiModelProperty("参数键值")
    @TableField("config_value")
    private String configValue;
    @ApiModelProperty("系统内置(Y是 N否)")
    @TableField("type")
    private String type;
    @ApiModelProperty("创建人")
    @TableField("create_by")
    private String createBy;
    @TableField("create_time")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    @TableField("update_by")
    private String updateBy;
    @TableField("update_time")
    private LocalDateTime updateTime;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysDictData.java
对比新文件
@@ -0,0 +1,64 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.gkhy.assess.common.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * 字典数据表
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Getter
@Setter
@TableName("sys_dict_data")
@ApiModel(value = "SysDictData对象", description = "字典数据表")
public class SysDictData extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("字典排序")
    @TableField("sort")
    private Integer sort;
    @NotBlank(message = "字典标签不能为空")
    @ApiModelProperty(value = "字典标签",required = true)
    @TableField("label")
    private String label;
    @NotBlank(message = "字典键值不能为空")
    @ApiModelProperty(value = "字典键值",required = true)
    @TableField("value")
    private String value;
    @NotBlank(message = "字典类型不能为空")
    @ApiModelProperty(value = "字典类型",required = true)
    @TableField("dict_type")
    private String dictType;
    @ApiModelProperty("是否默认(Y是 N否)")
    @TableField("is_default")
    private String isDefault;
    @ApiModelProperty("状态(0正常 1停用)")
    @TableField("status")
    private Integer status;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysDictType.java
对比新文件
@@ -0,0 +1,51 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.gkhy.assess.common.domain.BaseEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
 * <p>
 * 字典类型表
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Getter
@Setter
@TableName("sys_dict_type")
@ApiModel(value = "SysDictType对象", description = "字典类型表")
public class SysDictType extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @NotBlank(message = "字典名称不能为空")
    @ApiModelProperty(value = "字典名称",required = true)
    @TableField("name")
    private String name;
    @NotBlank(message = "字典类型不能为空")
    @ApiModelProperty(value = "字典类型",required = true)
    @TableField("dict_type")
    private String dictType;
    @ApiModelProperty("状态(0正常,1停用)")
    @TableField("status")
    private Integer status;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysLaw.java
对比新文件
@@ -0,0 +1,87 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
/**
 * <p>
 * 法律法规表
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Getter
@Setter
@TableName("sys_law")
@ApiModel(value = "SysLaw对象", description = "法律法规表")
@JsonInclude(NON_NULL)
public class SysLaw implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("住标题")
    @TableField("title")
    private String title;
    @ApiModelProperty("副标题")
    @TableField("sub_title")
    private String subTitle;
    @ApiModelProperty("内容")
    @TableField("content")
    private String content;
    @ApiModelProperty("法律法规类别")
    @TableField("law_type")
    private String lawType;
    @ApiModelProperty("颁布机构")
    @TableField("pub_agency")
    private String pubAgency;
    @ApiModelProperty("颁布日期")
    @TableField("pub_date")
    private LocalDateTime pubDate;
    @ApiModelProperty("状态(0正常,1关闭 默认0)")
    @TableField("status")
    private Integer status;
    @ApiModelProperty("创建人")
    @TableField("create_by")
    private String createBy;
    @ApiModelProperty("创建时间")
    @TableField("create_time")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    @TableField("update_by")
    private String updateBy;
    @ApiModelProperty("更新时间")
    @TableField("update_time")
    private LocalDateTime updateTime;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysNotice.java
对比新文件
@@ -0,0 +1,75 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.time.LocalDateTime;
import com.fasterxml.jackson.annotation.JsonInclude;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
/**
 * <p>
 * 通知表
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Getter
@Setter
@TableName("sys_notice")
@ApiModel(value = "SysNotice对象", description = "通知表")
@JsonInclude(NON_NULL)
public class SysNotice implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @NotBlank(message = "通知标题不能为空")
    @ApiModelProperty(value = "通知标题",required = true)
    @TableField("title")
    private String title;
    @NotBlank(message = "通知内容不能为空")
    @ApiModelProperty(value = "通知内容",required = true)
    @TableField("content")
    private String content;
    @ApiModelProperty("通知状态(0正常,1关闭 默认0)")
    @TableField("status")
    private Integer status;
    @ApiModelProperty("创建人")
    @TableField("create_by")
    private String createBy;
    @ApiModelProperty("创建时间")
    @TableField("create_time")
    private LocalDateTime createTime;
    @ApiModelProperty("更新人")
    @TableField("update_by")
    private String updateBy;
    @ApiModelProperty("更新时间")
    @TableField("update_time")
    private LocalDateTime updateTime;
    @ApiModelProperty("备注")
    @TableField("remark")
    private String remark;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysRegion.java
对比新文件
@@ -0,0 +1,53 @@
package com.gkhy.assess.system.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 java.io.Serializable;
import java.util.List;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
 * <p>
 * 系统地区表
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 13:45:45
 */
@Getter
@Setter
@Accessors(chain = true)
@TableName("sys_region")
@ApiModel(value = "SysRegion对象", description = "系统地区表")
public class SysRegion implements Serializable {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @ApiModelProperty("地区名称")
    @TableField("name")
    private String name;
    @ApiModelProperty("父主键")
    @TableField("parent_id")
    private Long parentId;
    @ApiModelProperty("排序")
    @TableField("sort")
    private Integer sort;
    @TableField(exist = false)
    private List<SysRegion> children;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/SysUser.java
对比新文件
@@ -0,0 +1,169 @@
package com.gkhy.assess.system.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.fasterxml.jackson.annotation.JsonInclude;
import com.gkhy.assess.common.domain.BaseEntity;
import com.gkhy.assess.common.validate.AgencyGroup;
import com.gkhy.assess.common.validate.ExpertGroup;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.time.LocalDateTime;
import java.util.List;
import static com.fasterxml.jackson.annotation.JsonInclude.Include.NON_NULL;
/**
 * <p>
 * 用户表
 * </p>
 *
 * @author kzy
 * @since 2023-10-17 14:26:29
 */
@Getter
@Setter
@TableName("sys_user")
@ApiModel(value = "SysUser对象", description = "用户表")
@Accessors(chain = true)
@JsonInclude(NON_NULL)
public class SysUser extends BaseEntity {
    private static final long serialVersionUID = 1L;
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    @NotBlank(message = "登录账号不能为空")
    @ApiModelProperty(value = "登录账号",required = true)
    @TableField("username")
    private String username;
    @ApiModelProperty("用户昵称/姓名")
    @TableField("name")
    private String name;
    @ApiModelProperty("用户身份(0代表监管用户,1代表机构用户,2代表专家用户)")
    @TableField("identity")
    private Integer identity;
    @ApiModelProperty("用户类型(0代表工作人员,1代表领导,默认0)")
    @TableField("user_type")
    private Integer userType;
    @ApiModelProperty("邮箱")
    @TableField("email")
    private String email;
    @NotBlank(message = "手机号码不能为空")
    @Length(min = 11, max = 11, message = "手机号只能为11位")
    @Pattern(regexp = "^1[345678]\\\\d{9}$",message = "手机号码有误!")
    @ApiModelProperty(value = "手机号码",required = true)
    @TableField("phone")
    private String phone;
    @ApiModelProperty("用户性别(0男,1女,2未知,默认2)")
    @TableField("sex")
    private Integer sex;
    @ApiModelProperty("头像路径")
    @TableField("avatar")
    private String avatar;
    @NotBlank(message = "密码不能为空")
    @ApiModelProperty(value = "密码",required = true)
    @TableField("password")
    private String password;
    @ApiModelProperty("盐加密")
    @TableField("salt")
    private String salt;
    @ApiModelProperty("账号状态(0正常,1停用,默认0)")
    @TableField("status")
    private Integer status;
    @ApiModelProperty("删除标志(0代表存在,1代表删除,默认0)")
    @TableField("del_flag")
    private Integer delFlag;
    @ApiModelProperty("管辖区域")
    @TableField("manage_region")
    private String manageRegion;
    @ApiModelProperty("机构id")
    @TableField("agency_id")
    private Long agencyId;
    @NotNull(message = "专家类型不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("专家类型")
    @TableField("expert_type")
    private Integer expertType;
//    @ApiModelProperty("社保一致性(0代表相同,1代表不同,默认0)")
//    @TableField("social_same")
//    private Integer socialSame;
    @NotBlank(message = "职务不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("职务")
    @TableField("post")
    private String post;
    @NotBlank(message = "职称不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("职称")
    @TableField("job_title")
    private String jobTitle;
    @NotBlank(message = "专业方向不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("专业方向")
    @TableField("major")
    private String major;
    @ApiModelProperty("审批状态(0审批通过,1待审批,2未通过 默认1)")
    @TableField("approve")
    private Integer approve;
    @ApiModelProperty("最后登录ip")
    @TableField("login_ip")
    private String loginIp;
    @ApiModelProperty("最后登录时间")
    @TableField("login_date")
    private LocalDateTime loginDate;
    @ApiModelProperty("密码最后更新时间")
    @TableField("pwd_update_date")
    private LocalDateTime pwdUpdateDate;
    @NotNull(message = "机构不能为空",groups ={AgencyGroup.class} )
    @ApiModelProperty("机构对象")
    @TableField(exist = false)
    private SysAgency agency;
    @NotNull(message = "社保照片不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("社保照片路径列表")
    @TableField(exist = false)
    private List<SysAttach> socialAttach;
    @NotNull(message = "医保照片不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("医保照片路径列表")
    @TableField(exist = false)
    private List<SysAttach> medicalAttach;
    @NotNull(message = "工资照片不能为空",groups ={ExpertGroup.class} )
    @ApiModelProperty("工资照片路径列表")
    @TableField(exist = false)
    private List<SysAttach> salaryAttach;
}
assess-system/src/main/java/com/gkhy/assess/system/domain/vo/UploadObjectVO.java
对比新文件
@@ -0,0 +1,22 @@
package com.gkhy.assess.system.domain.vo;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
@Getter
@Setter
@Accessors(chain = true)  //链式写法
@ApiModel(value = "上传文件返回对象", description = "上传文件返回对象")
public class UploadObjectVO {
    @ApiModelProperty("文件名称,前端访问图片链接格式:http://ip:port/api/images/文件保存相对路径")
    private String filename;
    @ApiModelProperty("文件保存相对路径")
    private String path;
//    @ApiModelProperty("访问链接")
//    private String url;
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysAgencyMapper.java
对比新文件
@@ -0,0 +1,46 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysAgency;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 * 机构表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:36
 */
@Mapper
public interface SysAgencyMapper extends BaseMapper<SysAgency> {
    /**
     * 根据名称获取机构
     * @param name
     * @return
     */
    SysAgency checkAgencyNameUnique(String name);
    /**
     * 根据id删除机构
     * @param agencyId
     * @return
     */
    int deleteAgencyById(Long agencyId);
    /**
     * 根据条件查询机构列表
     * @return
     */
    List<SysAgency> agencyList(SysAgency agency);
    /**
     * 根据id获取机构详情
     * @param AgencyId
     * @return
     */
    SysAgency getAgencyById(Long AgencyId);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysAttachMapper.java
对比新文件
@@ -0,0 +1,18 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysAttach;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * 系统配置表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 17:08:49
 */
@Mapper
public interface SysAttachMapper extends BaseMapper<SysAttach> {
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysConfigMapper.java
对比新文件
@@ -0,0 +1,25 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysConfig;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
 * <p>
 * 系统配置表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-13 08:39:55
 */
@Mapper
public interface SysConfigMapper extends BaseMapper<SysConfig> {
    /**
     * 查询参数配置信息
     * @param config
     * @return
     */
    public SysConfig getConfig(SysConfig config);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysDictDataMapper.java
对比新文件
@@ -0,0 +1,55 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysDictData;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * 字典数据表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Mapper
public interface SysDictDataMapper extends BaseMapper<SysDictData> {
    /**
     * 根系字典数据类型
     * @param oldDictType
     * @param newDictType
     * @return
     */
    int updateDictDataDictType(@Param("oldDictType") String oldDictType,  @Param("newDictType")String newDictType);
    /**
     *查询字典数据数量
     * @param dictType
     * @return
     */
    int countDictDataByType(String dictType);
    /**
     * 根据类型获取字典数据
     * @param dictType
     * @return
     */
    List<SysDictData> getDictDataByType(String dictType);
    /**
     * 根据id获取字典数据详情
     * @param dictId
     * @return
     */
    SysDictData getDictDataById(Long dictId);
    /**
     * 根据条件或字典数据
     * @param dictData
     * @return
     */
    List<SysDictData> dictDataList(SysDictData dictData);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysDictTypeMapper.java
对比新文件
@@ -0,0 +1,46 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysDictType;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 * 字典类型表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Mapper
public interface SysDictTypeMapper extends BaseMapper<SysDictType> {
    /**
     * 根据条件获取字典类型列表
     * @param dictType
     * @return
     */
    List<SysDictType> dictTypeList(SysDictType dictType);
    /**
     * 根据id获取字典类型
     * @param dictId
     * @return
     */
    SysDictType getDictTypeById(Long dictId);
    /**
     *校验字典类型称是否唯一
     * @param dictType
     * @return
     */
    SysDictType checkDictTypeUnique(String dictType);
    /**
     * 根据类型获取数据字典
     * @param dictType
     * @return
     */
    SysDictType getDictTypeByType(String dictType);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysLawMapper.java
对比新文件
@@ -0,0 +1,34 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysLaw;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gkhy.assess.system.domain.SysNotice;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 * 法律法规表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Mapper
public interface SysLawMapper extends BaseMapper<SysLaw> {
    /**
     * 根据条件获取法律法规列表
     * @param law
     * @return
     */
    List<SysLaw> lawList(SysLaw law);
    /**
     * 根据id获取lawId详情
     * @param lawId
     * @return
     */
    SysLaw getLawById(Long lawId);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysNoticeMapper.java
对比新文件
@@ -0,0 +1,34 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysNotice;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
 * <p>
 * 通知表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Mapper
public interface SysNoticeMapper extends BaseMapper<SysNotice> {
    /**
     * 根据条件获取通知列表
     * @param notice
     * @return
     */
    List<SysNotice> noticeList(SysNotice notice);
    /**
     * 根据id获取通知详情
     * @param noticeId
     * @return
     */
    SysNotice getNoticeById(Long noticeId);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysRegionMapper.java
对比新文件
@@ -0,0 +1,24 @@
package com.gkhy.assess.system.mapper;
import com.gkhy.assess.system.domain.SysRegion;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
 * <p>
 * 系统地区表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 13:45:45
 */
@Mapper
public interface SysRegionMapper extends BaseMapper<SysRegion> {
    /**
     * 校验同级名称是否唯一
     * @param name
     * @return
     */
    SysRegion checkRegionUnique(@Param("name") String name, @Param("parentId")Long parentId);
}
assess-system/src/main/java/com/gkhy/assess/system/mapper/SysUserMapper.java
对比新文件
@@ -0,0 +1,111 @@
package com.gkhy.assess.system.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.gkhy.assess.system.domain.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
 * 用户表 Mapper 接口
 * </p>
 *
 * @author kzy
 * @since 2023-10-17 14:26:29
 */
@Mapper
public interface SysUserMapper extends BaseMapper<SysUser> {
    /**
     * 根据登录名获取用户
     * @param username
     * @return
     */
    public SysUser getUserByUsername(String username);
    /**
     * 根据登录名或者手机号获取用户
     * @param username
     * @return
     */
    public SysUser getUserByUsernamePhone(String username);
    /**
     * 获取监管用户列表
     * @param user
     * @return
     */
    List<SysUser> monitorList(SysUser user);
    /**
     * 获取机构用户列表
     * @param user
     * @return
     */
    List<SysUser> agencyList(SysUser user);
    /**
     * 获取专家用户列表
     * @param user
     * @return
     */
    List<SysUser> expertList(SysUser user);
    /**
     * 根据手机号获取用户
     * @param phone
     * @return
     */
    public SysUser getUserByPhone(String phone);
    /**
     * 根据email获取用户
     * @param email
     * @return
     */
    public SysUser getUserByEmail(String email);
    /**
     * 根据用户id获取用户
     * @param userId
     * @return
     */
    public SysUser getUserById(Long userId);
    /**
     * 删除用户
     * @param userId
     * @return
     */
    public int deleteUserById(Long userId);
    /**
     * 批量删除用户
     * @param userIds
     * @return
     */
    public int deleteUserByIds(Long[] userIds);
    /**
     * 校验用户名称是否唯一
     * @param username
     * @return
     */
    SysUser checkLoginNameUnique(String username);
    /**
     * 校验手机号是否唯一
     * @param phone
     * @return
     */
    SysUser checkPhoneUnique(String phone);
    /**
     * 校验邮箱是否唯一
     * @param email
     * @return
     */
    SysUser checkEmailUnique(String email);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysAgencyService.java
对比新文件
@@ -0,0 +1,38 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.system.domain.SysAgency;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gkhy.assess.system.domain.SysUser;
/**
 * <p>
 * 机构表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:36
 */
public interface SysAgencyService extends IService<SysAgency> {
    /**
     * 根据条件分页查询机构列表
     * @param agency
     * @return
     */
    CommonPage agencyList(SysAgency agency);
    /**
     * 校验机构名称是否唯一
     * @param agency
     * @return
     */
    Boolean checkAgencyNameUnique(SysAgency agency);
    /**
     * 根据id获取机构详情
     * @param agencyId
     * @return
     */
    SysAgency getAgencyById(Long agencyId);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysAttachService.java
对比新文件
@@ -0,0 +1,16 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.system.domain.SysAttach;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 系统配置表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 17:08:49
 */
public interface SysAttachService extends IService<SysAttach> {
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysCommonService.java
对比新文件
@@ -0,0 +1,14 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.system.domain.vo.UploadObjectVO;
import org.springframework.web.multipart.MultipartFile;
public interface SysCommonService {
    /**
     * 上传图像或者文件
     * @param file
     * @return
     */
    public UploadObjectVO uploadFile(MultipartFile file);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysConfigService.java
对比新文件
@@ -0,0 +1,22 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.system.domain.SysConfig;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 系统配置表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-13 08:39:55
 */
public interface SysConfigService extends IService<SysConfig> {
    /**
     * 根据键名查询配置信息
     * @param configKey
     * @return
     */
    public String getConfigByKey(String configKey);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysDictDataService.java
对比新文件
@@ -0,0 +1,59 @@
package com.gkhy.assess.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.system.domain.SysDictData;
import com.gkhy.assess.system.domain.SysDictType;
/**
 * <p>
 * 字典数据表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
public interface SysDictDataService extends IService<SysDictData> {
    /**
     * 根据id获取数据字典数据详情
     * @param dictId
     * @return
     */
    SysDictData getDictDataById(Long dictId);
    /**
     * 新增字典数据
     * @param dictData
     * @return
     */
    int addDictData(SysDictData dictData);
    /**
     * 修改字典数据
     * @param dictData
     * @return
     */
    int editDictData(SysDictData dictData);
    /**
     * 根据id删除字典数据
     * @param dictId
     * @return
     */
    int deleteDictDataById(Long dictId);
    /**
     * 字典类型状态修改
     * @param dictData
     * @return
     */
    int changeDictDataStatus(SysDictData dictData);
    /**
     * 分页获取字典数据
     * @param dictData
     * @return
     */
    CommonPage dictDataList(SysDictData dictData);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysDictTypeService.java
对比新文件
@@ -0,0 +1,85 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.system.domain.SysDictData;
import com.gkhy.assess.system.domain.SysDictType;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 * 字典类型表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
public interface SysDictTypeService extends IService<SysDictType> {
    /**
     * 分页获取数据字典类型
     * @param dictType
     * @return
     */
    CommonPage dictTypeList(SysDictType dictType);
    /**
     * 根据id获取数据字典类型详情
     * @param dictId
     * @return
     */
    SysDictType getDictTypeById(Long dictId);
    /**
     * 新增字典类型
     * @param dictType
     * @return
     */
    int addDictType(SysDictType dictType);
    /**
     * 修改字典类型
     * @param dictType
     * @return
     */
    int editDictType(SysDictType dictType);
    /**
     * 根据id删除字典类型
     * @param dictId
     * @return
     */
    int deleteDictTypeById(Long dictId);
    /**
     * 字典类型状态修改
     * @param dictType
     * @return
     */
    int changeDictTypeStatus(SysDictType dictType);
    /**
     * 校验字典类型称是否唯一
     *
     * @param dictType 字典类型
     * @return 结果
     */
    boolean checkDictTypeUnique(SysDictType dictType);
    /**
     * 根据字典类型查询字典数据
     *
     * @param dictType 字典类型
     * @return 字典数据集合信息
     */
     List<SysDictData> getDictDataByType(String dictType);
    /**
     * 根据字典类型查询信息
     *
     * @param dictType 字典类型
     * @return 字典类型
     */
    SysDictType getDictTypeByType(String dictType);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysLawService.java
对比新文件
@@ -0,0 +1,59 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.system.domain.SysLaw;
import com.baomidou.mybatisplus.extension.service.IService;
import com.gkhy.assess.system.domain.SysNotice;
/**
 * <p>
 * 法律法规表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
public interface SysLawService extends IService<SysLaw> {
    /**
     * 分页获取法律法规列表
     * @param law
     * @return
     */
    CommonPage lawList(SysLaw law);
    /**
     * 根据id获取法律法规详情
     * @param lawId
     * @return
     */
    SysLaw getLawById(Long lawId);
    /**
     * 新增法律法规
     * @param law
     * @return
     */
    int addLaw(SysLaw law);
    /**
     * 修改法律法规
     * @param law
     * @return
     */
    int editLaw(SysLaw law);
    /**
     * 删除法律法规
     * @param lawId
     * @return
     */
    int deleteLawById(Long lawId);
    /**
     * 修改法律法规状态
     * @param law
     * @return
     */
    int changeLawStatus(SysLaw law);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysNoticeService.java
对比新文件
@@ -0,0 +1,58 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.system.domain.SysNotice;
import com.baomidou.mybatisplus.extension.service.IService;
/**
 * <p>
 * 通知表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
public interface SysNoticeService extends IService<SysNotice> {
    /**
     * 分页获取通知列表
     * @param notice
     * @return
     */
    CommonPage noticeList(SysNotice notice);
    /**
     * 根据id获取通知详情
     * @param noticeId
     * @return
     */
    SysNotice getNoticeById(Long noticeId);
    /**
     * 新增通知
     * @param notice
     * @return
     */
    int addNotice(SysNotice notice);
    /**
     * 修改通知
     * @param notice
     * @return
     */
    int editNotice(SysNotice notice);
    /**
     * 删除通知
     * @param noticeId
     * @return
     */
    int deleteNoticeById(Long noticeId);
    /**
     * 修改通知状态
     * @param notice
     * @return
     */
    int changeNoticeStatus(SysNotice notice);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysRegionService.java
对比新文件
@@ -0,0 +1,51 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.system.domain.SysRegion;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 * 系统地区表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 13:45:45
 */
public interface SysRegionService extends IService<SysRegion> {
    /**
     * 地区列表(树形结构)
     * @param region
     * @return
     */
    List<SysRegion> regionTree(SysRegion region);
    /**
     * 新增地区
     * @param region
     * @return
     */
    int addRegion(SysRegion region);
    /**
     * 修改地区
     * @param region
     * @return
     */
    int editRegion(SysRegion region);
    /**
     * 根据id删除地区
     * @param reginId
     * @return
     */
    int deleteRegionById(Long reginId);
    /**
     * 获取子地区
     * @param regionId
     * @return
     */
    List<SysRegion> getChildRegionById(Long regionId);
}
assess-system/src/main/java/com/gkhy/assess/system/service/SysUserService.java
对比新文件
@@ -0,0 +1,179 @@
package com.gkhy.assess.system.service;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.domain.vo.AccountVO;
import com.gkhy.assess.common.domain.vo.LoginBody;
import com.gkhy.assess.system.domain.SysUser;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
 * <p>
 * 用户表 服务类
 * </p>
 *
 * @author kzy
 * @since 2023-10-17 14:26:29
 */
public interface SysUserService extends IService<SysUser> {
    /**
     * 登录
     * @param loginBody
     * @return
     */
    AccountVO login(LoginBody loginBody);
    /**
     * 退出
     */
    void logout();
    /**
     * 根据条件分页查询监管用户列表
     * @param user
     * @return
     */
    CommonPage monitorList(SysUser user);
    /**
     * 根据条件分页查询机构用户列表
     * @param user
     * @return
     */
    CommonPage agencyList(SysUser user);
    /**
     * 根据条件分页查询专家用户列表
     * @param user
     * @return
     */
    CommonPage expertList(SysUser user);
    /**
     * 根据登录名获取用户
     * @param username
     * @return
     */
    SysUser getUserByUsername(String username);
    /**
     * 登录名或者手机号获取用户
     * @param username
     * @return
     */
    SysUser getUserByUsernamePhone(String username);
    /**
     * 机构用户注册
     * @param user
     * @return
     */
    int agencyRegister(SysUser user);
    /**
     * 创建专家
     * @param user
     * @return
     */
    int addExpert(SysUser user);
    /**
     * 根据手机号获取用户
     * @param phone
     * @return
     */
    SysUser getUserByPhone(String phone);
    /**
     * 根据id获取用户
     * @param userId
     * @return
     */
    SysUser getUserById(Long userId);
    /**
     * 根据id删除用户
     * @param userId
     * @return
     */
    int deleteUserById(Long userId);
    /**
     * 编辑机构用户
     * @param user
     * @return
     */
    int editAgency(SysUser user);
    /**
     * 编辑专家用户
     * @param user
     * @return
     */
    int editExpert(SysUser user);
    /**
     * 修改用户密码信息
     * @param user
     * @return
     */
    boolean resetUserPwd(SysUser user);
    /**
     * 校验登录名是否唯一
     * @param user
     * @return
     */
    boolean checkUsernameUnique(SysUser user);
    /**
     * 校验手机号是否唯一
     * @param user
     * @return
     */
    boolean checkPhoneUnique(SysUser user);
    /**
     * 校验邮箱是否唯一
     * @param user
     * @return
     */
    boolean checkEmailUnique(SysUser user);
    /**
     * 校验用户是否允许操作
     * @param user
     */
    void checkUserAllowed(SysUser user);
    /**
     * 校验用户是否有数据权限
     * @param userId
     */
    void checkUserDataScope(Long userId);
    /**
     * 导入用户数据
     * @param userList
     * @param isUpdateSupport  是否更新支持,如果已存在,则进行更新数据
     * @return
     */
    String importUser(List<SysUser> userList,Boolean isUpdateSupport);
    /**
     * 修改用户状态
     * @param user
     * @return
     */
    boolean changeUserStatus(SysUser user);
    /**
     * 修改审批状态
     * @param user
     * @return
     */
    boolean changeApprove(SysUser user);
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysAgencyServiceImpl.java
对比新文件
@@ -0,0 +1,47 @@
package com.gkhy.assess.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.system.domain.SysAgency;
import com.gkhy.assess.system.mapper.SysAgencyMapper;
import com.gkhy.assess.system.service.SysAgencyService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 机构表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:36
 */
@Service
public class SysAgencyServiceImpl extends ServiceImpl<SysAgencyMapper, SysAgency> implements SysAgencyService {
    @Override
    public CommonPage agencyList(SysAgency agency) {
        PageUtil.startPage();
        List<SysAgency> agencyList=baseMapper.agencyList(agency);
        return CommonPage.restPage(agencyList);
    }
    @Override
    public Boolean checkAgencyNameUnique(SysAgency agency) {
        Long agencyId = agency.getId()==null? -1L : agency.getId();
        SysAgency info = baseMapper.checkAgencyNameUnique(agency.getName());
        if (info!=null && info.getId().longValue() != agencyId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public SysAgency getAgencyById(Long agencyId) {
        return baseMapper.getAgencyById(agencyId);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysAttachServiceImpl.java
对比新文件
@@ -0,0 +1,20 @@
package com.gkhy.assess.system.service.impl;
import com.gkhy.assess.system.domain.SysAttach;
import com.gkhy.assess.system.mapper.SysAttachMapper;
import com.gkhy.assess.system.service.SysAttachService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 系统配置表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 17:08:49
 */
@Service
public class SysAttachServiceImpl extends ServiceImpl<SysAttachMapper, SysAttach> implements SysAttachService {
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysCommonServiceImpl.java
对比新文件
@@ -0,0 +1,72 @@
package com.gkhy.assess.system.service.impl;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.system.domain.vo.UploadObjectVO;
import com.gkhy.assess.system.service.SysCommonService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.UUID;
@Service
public class SysCommonServiceImpl implements SysCommonService {
    @Value("${image.upload_file}")
    private String uploadFilePath;
    @Value("${image.upload_image}")
    private String uploadImagePath;
    @Override
    public UploadObjectVO uploadFile(MultipartFile file) {
        UploadObjectVO uploadObjectVO=doUpload(file);
        return uploadObjectVO;
    }
    public UploadObjectVO doUpload(MultipartFile file){
        String filename=file.getOriginalFilename();
        String subfix=filename.substring(filename.lastIndexOf("."));
        filename= UUID.randomUUID().toString().replace("-","")+subfix;
        String systemDir=System.getProperty("user.dir");
        String filePath="";
        if(checkImageType(subfix)){
            filePath=uploadImagePath;
        }else{
            filePath=uploadFilePath;
        }
        File dirFile=new File(filePath);
        if(!dirFile.exists()){
            dirFile.mkdirs();
        }
        filePath=filePath+File.separator+filename;
        try {
            file.transferTo(new File(systemDir+File.separator+filePath));
        } catch (FileNotFoundException e) {
            throw new ApiException("找不到文件");
        } catch (IOException e) {
            throw new ApiException("发生错误,请联系管理员");
        }
        UploadObjectVO uploadObjectVO=new UploadObjectVO().setFilename(filename)
                .setPath(filePath);
        return uploadObjectVO;
    }
    public boolean checkImageType(String subfix){
        if(".jpg".equalsIgnoreCase(subfix)||
                ".jpeg".equalsIgnoreCase(subfix)||
                ".png".equalsIgnoreCase(subfix)||
                ".bmp".equalsIgnoreCase(subfix)||
                ".tif".equalsIgnoreCase(subfix)
        ){
            return true;
        }
        return false;
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysConfigServiceImpl.java
对比新文件
@@ -0,0 +1,49 @@
package com.gkhy.assess.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.constant.CacheConstant;
import com.gkhy.assess.common.utils.RedisUtils;
import com.gkhy.assess.system.domain.SysConfig;
import com.gkhy.assess.system.mapper.SysConfigMapper;
import com.gkhy.assess.system.service.SysConfigService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 系统配置表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-13 08:39:55
 */
@Service
public class SysConfigServiceImpl extends ServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService {
    @Autowired
    private RedisUtils redisUtils;
    @Override
    public String getConfigByKey(String configKey) {
        String redisKey=getCacheKey(configKey);
        String configValue= (String) redisUtils.get(redisKey);
        if(StrUtil.isNotEmpty(configValue)){
            return configValue;
        }
        SysConfig retConfig=baseMapper.getConfig(new SysConfig().setConfigKey(configKey));
        if(ObjectUtil.isNotNull(retConfig)){
            redisUtils.set(redisKey,retConfig.getConfigValue());
            return retConfig.getConfigValue();
        }
        return StrUtil.EMPTY;
    }
    private String getCacheName(){
        return CacheConstant.SYS_CONFIG_CACHE;
    }
    private String getCacheKey(String configKey){
        return CacheConstant.SYS_CONFIG_KEY+configKey;
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysDictDataServiceImpl.java
对比新文件
@@ -0,0 +1,68 @@
package com.gkhy.assess.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.system.domain.SysDictData;
import com.gkhy.assess.system.mapper.SysDictDataMapper;
import com.gkhy.assess.system.service.SysDictDataService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 字典数据表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Service
public class SysDictDataServiceImpl extends ServiceImpl<SysDictDataMapper, SysDictData> implements SysDictDataService {
    @Override
    public SysDictData getDictDataById(Long dictId) {
        return baseMapper.getDictDataById(dictId);
    }
    @Override
    public int addDictData(SysDictData dictData) {
        boolean b=save(dictData);
        if(!b){
            throw new ApiException("新增字典数据失败");
        }
        return 1;
    }
    @Override
    public int editDictData(SysDictData dictData) {
        boolean b=updateById(dictData);
        if(!b){
            throw new ApiException("修改字典数据失败");
        }
        return 1;
    }
    @Override
    public int deleteDictDataById(Long dictId) {
        boolean b=removeById(dictId);
        if(!b){
            throw new ApiException("删除字典数据失败");
        }
        return 1;
    }
    @Override
    public int changeDictDataStatus(SysDictData dictData) {
        return editDictData(dictData);
    }
    @Override
    public CommonPage dictDataList(SysDictData dictData) {
        PageUtil.startPage();
        List<SysDictData> dictList=baseMapper.dictDataList(dictData);
        return CommonPage.restPage(dictList);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysDictTypeServiceImpl.java
对比新文件
@@ -0,0 +1,108 @@
package com.gkhy.assess.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.system.domain.SysDictData;
import com.gkhy.assess.system.domain.SysDictType;
import com.gkhy.assess.system.domain.SysLaw;
import com.gkhy.assess.system.mapper.SysDictDataMapper;
import com.gkhy.assess.system.mapper.SysDictTypeMapper;
import com.gkhy.assess.system.service.SysDictTypeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
 * <p>
 * 字典类型表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-01 15:37:51
 */
@Service
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements SysDictTypeService {
    @Autowired
    private SysDictDataMapper dictDataMapper;
    @Override
    public CommonPage dictTypeList(SysDictType dictType) {
        PageUtil.startPage();
        List<SysDictType> dictList=baseMapper.dictTypeList(dictType);
        return CommonPage.restPage(dictList);
    }
    @Override
    public SysDictType getDictTypeById(Long dictId) {
        return baseMapper.getDictTypeById(dictId);
    }
    @Override
    public int addDictType(SysDictType dictType) {
        boolean b=save(dictType);
        if(!b){
            throw new ApiException("新增字典类型失败");
        }
        return 1;
    }
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int editDictType(SysDictType dict) {
        SysDictType oldDict= baseMapper.getDictTypeById(dict.getId());
        dictDataMapper.updateDictDataDictType(oldDict.getDictType(), dict.getDictType());
        boolean b=updateById(dict);
        if(!b){
            throw new ApiException("修改数据字典类型失败");
        }
        return 1;
    }
    @Override
    public int deleteDictTypeById(Long dictId) {
        SysDictType dictType=getDictTypeById(dictId);
        if(dictDataMapper.countDictDataByType(dictType.getDictType())>0){
            throw new ApiException(String.format("%1$s已分配,不能删除", dictType.getName()));
        }
        boolean b=removeById(dictId);
        if(!b){
            throw new ApiException("删除字典类型失败");
        }
        return 1;
    }
    @Override
    public int changeDictTypeStatus(SysDictType dictType) {
        boolean b=updateById(dictType);
        if(!b){
            throw new ApiException("修改数据字典类型失败");
        }
        return 1;
    }
    @Override
    public boolean checkDictTypeUnique(SysDictType dict) {
        Long dictId = ObjectUtil.isNull(dict.getId()) ? -1L : dict.getId();
        SysDictType dictType = baseMapper.checkDictTypeUnique(dict.getDictType());
        if (ObjectUtil.isNotNull(dictType) && dictType.getId().longValue() != dictId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public List<SysDictData> getDictDataByType(String dictType) {
        return dictDataMapper.getDictDataByType(dictType);
    }
    @Override
    public SysDictType getDictTypeByType(String dictType) {
        return baseMapper.getDictTypeByType(dictType);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysLawServiceImpl.java
对比新文件
@@ -0,0 +1,69 @@
package com.gkhy.assess.system.service.impl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.system.domain.SysLaw;
import com.gkhy.assess.system.domain.SysNotice;
import com.gkhy.assess.system.mapper.SysLawMapper;
import com.gkhy.assess.system.service.SysLawService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 法律法规表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Service
public class SysLawServiceImpl extends ServiceImpl<SysLawMapper, SysLaw> implements SysLawService {
    @Override
    public CommonPage lawList(SysLaw law) {
        PageUtil.startPage();
        List<SysLaw> lawList=baseMapper.lawList(law);
        return CommonPage.restPage(lawList);
    }
    @Override
    public SysLaw getLawById(Long lawId) {
        return baseMapper.getLawById(lawId);
    }
    @Override
    public int addLaw(SysLaw law) {
        boolean b=save(law);
        if(!b){
            throw new ApiException("新增法律法规失败");
        }
        return 1;
    }
    @Override
    public int editLaw(SysLaw law) {
        boolean b=updateById(law);
        if(!b){
            throw new ApiException("修改法律法规失败");
        }
        return 1;
    }
    @Override
    public int deleteLawById(Long lawId) {
        boolean b=removeById(lawId);
        if(!b){
            throw new ApiException("删除法律法规失败");
        }
        return 1;
    }
    @Override
    public int changeLawStatus(SysLaw law) {
        return editLaw(law);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysNoticeServiceImpl.java
对比新文件
@@ -0,0 +1,68 @@
package com.gkhy.assess.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.system.domain.SysNotice;
import com.gkhy.assess.system.mapper.SysNoticeMapper;
import com.gkhy.assess.system.service.SysNoticeService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * <p>
 * 通知表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-23 16:04:37
 */
@Service
public class SysNoticeServiceImpl extends ServiceImpl<SysNoticeMapper, SysNotice> implements SysNoticeService {
    @Override
    public CommonPage noticeList(SysNotice notice) {
        PageUtil.startPage();
        List<SysNotice> noticeList=baseMapper.noticeList(notice);
        return CommonPage.restPage(noticeList);
    }
    @Override
    public SysNotice getNoticeById(Long noticeId) {
        return baseMapper.getNoticeById(noticeId);
    }
    @Override
    public int addNotice(SysNotice notice) {
        boolean b=save(notice);
        if(!b){
            throw new ApiException("新增通知失败");
        }
        return 1;
    }
    @Override
    public int editNotice(SysNotice notice) {
        boolean b=updateById(notice);
        if(!b){
            throw new ApiException("修改通知失败");
        }
        return 1;
    }
    @Override
    public int deleteNoticeById(Long noticeId) {
        boolean b=removeById(noticeId);
        if(!b){
            throw new ApiException("删除通知失败");
        }
        return 1;
    }
    @Override
    public int changeNoticeStatus(SysNotice notice) {
        return editNotice(notice);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysRegionServiceImpl.java
对比新文件
@@ -0,0 +1,110 @@
package com.gkhy.assess.system.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.system.domain.SysRegion;
import com.gkhy.assess.system.domain.SysUser;
import com.gkhy.assess.system.mapper.SysRegionMapper;
import com.gkhy.assess.system.service.SysRegionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
 * <p>
 * 系统地区表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-11-24 13:45:45
 */
@Service
public class SysRegionServiceImpl extends ServiceImpl<SysRegionMapper, SysRegion> implements SysRegionService {
    @Override
    public List<SysRegion> regionTree(SysRegion region) {
        LambdaQueryWrapper<SysRegion> lambdaQueryWrapper = Wrappers.<SysRegion>lambdaQuery();
        if(StrUtil.isNotBlank(region.getName())){
            lambdaQueryWrapper.like(SysRegion::getName,region.getName());
        }
        lambdaQueryWrapper.orderBy(true, true,SysRegion::getSort);
        List<SysRegion> regions= list(lambdaQueryWrapper);
        //筛选出所有一级标签
        return regions.stream()
                .filter(tagEntity -> tagEntity.getParentId()==0L)
                .peek(tagEntity -> tagEntity.setChildren(this.listRegionChildren(tagEntity,regions)))
                .sorted(Comparator.comparing(SysRegion::getSort))
                .collect(Collectors.toList());
    }
    public List<SysRegion> listRegionChildren(SysRegion region,List<SysRegion> regions){
        //递归查找子类
        return regions.stream()
                .filter(regionEntity -> Objects.equals(regionEntity.getParentId(), region.getId()))
                .peek(regionEntity -> regionEntity.setChildren(this.listRegionChildren(regionEntity,regions)))
                //.sorted(Comparator.comparing(SysRegion::getSort))
                .collect(Collectors.toList());
    }
    @Override
    public int addRegion(SysRegion region) {
        if(!checkRegionUnique(new SysRegion().setName(region.getName()))){
            throw new ApiException("已存在相同地区名称");
        }
        boolean b=save(region);
        if(!b){
            throw new ApiException("新增地区失败");
        }
        return 0;
    }
    public boolean checkRegionUnique(SysRegion region){
        Long userId = region.getId()==null? -1L : region.getId();
        SysRegion info = baseMapper.checkRegionUnique(region.getName(),region.getParentId()==null?0L:region.getParentId());
        if (info!=null && info.getId().longValue() != userId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public int editRegion(SysRegion region) {
        if(!checkRegionUnique(new SysRegion().setName(region.getName()))){
            throw new ApiException("已存在相同地区名称");
        }
        boolean b=updateById(region);
        if(!b){
            throw new ApiException("修改地区失败");
        }
        return 0;
    }
    @Override
    public int deleteRegionById(Long reginId) {
        Long count=count(Wrappers.<SysRegion>lambdaQuery()
                .eq(true,SysRegion::getParentId,reginId));
        if(count>0){
            throw new ApiException("下级存在区县数据");
        }
        boolean b=removeById(reginId);
        if(!b){
            throw new ApiException("删除地区失败");
        }
        return 0;
    }
    @Override
    public List<SysRegion> getChildRegionById(Long regionId) {
        return list(Wrappers.<SysRegion>lambdaQuery()
                .eq(true,SysRegion::getParentId,regionId));
    }
}
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java
对比新文件
@@ -0,0 +1,374 @@
package com.gkhy.assess.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.constant.CacheConstant;
import com.gkhy.assess.common.domain.vo.AccountVO;
import com.gkhy.assess.common.domain.vo.LoginBody;
import com.gkhy.assess.common.enums.UserIdentityEnum;
import com.gkhy.assess.common.enums.UserTypeEnum;
import com.gkhy.assess.common.exception.ApiException;
import com.gkhy.assess.common.utils.BeanValidators;
import com.gkhy.assess.common.utils.JwtTokenUtil;
import com.gkhy.assess.common.utils.PageUtil;
import com.gkhy.assess.common.utils.RedisUtils;
import com.gkhy.assess.system.domain.*;
import com.gkhy.assess.system.mapper.SysAgencyMapper;
import com.gkhy.assess.system.mapper.SysUserMapper;
import com.gkhy.assess.system.service.SysConfigService;
import com.gkhy.assess.system.utils.ShiroUtils;
import com.gkhy.assess.system.service.SysUserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Validator;
import java.util.List;
/**
 * <p>
 * 用户表 服务实现类
 * </p>
 *
 * @author kzy
 * @since 2023-10-17 14:26:29
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private SysConfigService configService;
    @Autowired
    private Validator validator;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SysAgencyMapper agencyMapper;
    @Override
    public AccountVO login(LoginBody loginBody) {
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginBody.getUsername(), loginBody.getPassword(), false);
        Subject subject= SecurityUtils.getSubject();
        String msg ;
        try {
            subject.login(usernamePasswordToken);
            SysUser sysUser = (SysUser) subject.getPrincipal();
            AccountVO accountVO = new AccountVO();
            BeanUtils.copyProperties(sysUser, accountVO);
            String token = JwtTokenUtil.sign(sysUser.getUsername(),sysUser.getPassword());
            accountVO.setToken(token);
            String key= redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+":"+JwtTokenUtil.md5Encode(token));
            // 设置超时时间
            redisUtils.set(key,token);
            redisUtils.expire(key,JwtTokenUtil.EXPIRATION*2/1000);
            return accountVO;
        }catch (UnknownAccountException | IncorrectCredentialsException uae){
            throw new ApiException("用户名/密码错误,请重新输入");
        } catch (LockedAccountException lae) { // 账号已被锁定
            msg = "账号已被锁定";
            throw new ApiException(msg);
        } catch (AuthenticationException ae) { // 其他身份验证异常
            msg = "用户认证失败";
            throw new ApiException(msg);
        }
    }
    @Override
    public void logout() {
        String jwtToken = request.getHeader(JwtTokenUtil.USER_LOGIN_TOKEN);
        String key= redisUtils.generateKey(CacheConstant.SYS_USER_TOKEN+":"+JwtTokenUtil.md5Encode(jwtToken));
        //删除redis缓存
        redisUtils.del(key);
    }
    @Override
    public CommonPage<SysUser> monitorList(SysUser user) {
        PageUtil.startPage();
        List<SysUser> users=baseMapper.monitorList(user);
        return CommonPage.restPage(users);
    }
    @Override
    public CommonPage<SysUser> agencyList(SysUser user) {
        PageUtil.startPage();
        List<SysUser> users=baseMapper.agencyList(user);
        return CommonPage.restPage(users);
    }
    @Override
    public CommonPage<SysUser> expertList(SysUser user) {
        PageUtil.startPage();
        List<SysUser> users=baseMapper.expertList(user);
        return CommonPage.restPage(users);
    }
    @Override
    public SysUser getUserByUsername(String username) {
        String key=redisUtils.generateKey(CacheConstant.SYS_USER_NAME+":"+username);
        SysUser sysUser =null;
        if(redisUtils.hasKey(key)){
            sysUser= (SysUser) redisUtils.get(key);
        }else {
            sysUser = baseMapper.getUserByUsername(username);
            redisUtils.set(key,sysUser,10*60);
        }
        return sysUser;
    }
    @Override
    public SysUser getUserByUsernamePhone(String username) {
        String key=redisUtils.generateKey(CacheConstant.SYS_USER_NAME+":"+username);
        SysUser sysUser =null;
        if(redisUtils.hasKey(key)){
            sysUser= (SysUser) redisUtils.get(key);
        }else {
            sysUser = baseMapper.getUserByUsernamePhone(username);
            redisUtils.set(key,sysUser,10*60);
        }
        return sysUser;
    }
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int agencyRegister(SysUser user) {
        //校验用户信息
        if(!checkUsernameUnique(new SysUser().setUsername(user.getUsername()))){
            throw new ApiException("用户名已存在");
        }
        if(!checkPhoneUnique(new SysUser().setUsername(user.getPhone()))){
            throw new ApiException("手机号已存在");
        }
        SysAgency agency=user.getAgency();
        if(ObjectUtil.isNull(agency)){
            throw new ApiException("机构信息不能为空");
        }
        //查询机构信息是否存在
        if(ObjectUtil.isNotNull(agencyMapper.checkAgencyNameUnique(agency.getName()))){
            throw new ApiException("机构名称已存在");
        }
        int i=agencyMapper.insert(agency);
        if(i<1){
            throw new ApiException("保存机构信息失败");
        }
        user.setAgencyId(agency.getId());
        user.setUserType(UserIdentityEnum.AGENCY.getCode());
        boolean b=save(user);
        if(!b){
            throw new ApiException("创建机构用户信息失败");
        }
        return 1;
    }
    @Override
    public int addExpert(SysUser user) {
        //校验用户信息
        if(!checkUsernameUnique(new SysUser().setUsername(user.getUsername()))){
            throw new ApiException("用户名已存在");
        }
        if(!checkPhoneUnique(new SysUser().setUsername(user.getPhone()))){
            throw new ApiException("手机号已存在");
        }
        user.setUserType(UserIdentityEnum.EXPERT.getCode());
        user.setCreateBy(ShiroUtils.getSysUser().getUsername());
        boolean b=save(user);
        if(!b){
            throw new ApiException("创建专家信息失败");
        }
        return 1;
    }
    @Override
    public SysUser getUserByPhone(String phone) {
        return baseMapper.getUserByPhone(phone);
    }
    @Override
    public SysUser getUserById(Long userId) {
        return baseMapper.getUserById(userId);
    }
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int deleteUserById(Long userId) {
        SysUser user=getUserById(userId);
        //机构用户,将机构信息设置成删除状态
        if(user.getUserType().equals(UserIdentityEnum.AGENCY.getCode())){
            agencyMapper.deleteAgencyById(user.getAgencyId());
        }
        return baseMapper.deleteUserById(userId);
    }
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public int editAgency(SysUser user) {
        //校验用户信息
        if(!checkUsernameUnique(user)){
            throw new ApiException("用户名已存在");
        }
        if(!checkPhoneUnique(user)){
            throw new ApiException("手机号已存在");
        }
        SysAgency agency=user.getAgency();
        if(ObjectUtil.isNull(agency)){
            throw new ApiException("机构信息不能为空");
        }
        //查询机构信息是否存在
        if(ObjectUtil.isNotNull(agency)){
            throw new ApiException("机构名称已存在");
        }
        agencyMapper.updateById(agency);
        boolean b=updateById(user);
        if(!b){
            throw new ApiException("更新用户失败");
        }
        return 1;
    }
    @Override
    public int editExpert(SysUser user) {
        //校验用户信息
        if(!checkUsernameUnique(user)){
            throw new ApiException("用户名已存在");
        }
        if(!checkPhoneUnique(user)){
            throw new ApiException("手机号已存在");
        }
        boolean b=updateById(user);
        if(!b){
            throw new ApiException("更新专家信息失败");
        }
        return 1;
    }
    @Override
    public boolean resetUserPwd(SysUser user) {
        return updateById(user);
    }
    @Override
    public boolean checkUsernameUnique(SysUser user) {
        Long userId = user.getId()==null? -1L : user.getId();
        SysUser info = baseMapper.checkLoginNameUnique(user.getUsername());
        if (info!=null && info.getId().longValue() != userId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public boolean checkPhoneUnique(SysUser user) {
        Long userId = user.getId()==null ? -1L : user.getId();
        SysUser info = baseMapper.checkPhoneUnique(user.getPhone());
        if (info!=null && info.getId().longValue() != userId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public boolean checkEmailUnique(SysUser user) {
        Long userId = user.getId()==null ? -1L : user.getId();
        SysUser info = baseMapper.checkEmailUnique(user.getEmail());
        if (info!=null && info.getId().longValue() != userId.longValue())
        {
            return false;
        }
        return true;
    }
    @Override
    public void checkUserAllowed(SysUser user) {
    }
    @Override
    public void checkUserDataScope(Long userId) {
        SysUser user = baseMapper.getUserById(userId);
        if (ObjectUtil.isNull(user))
        {
            throw new ApiException("用户数据不存在!");
        }
    }
    @Override
    public String importUser(List<SysUser> userList,Boolean isUpdateSupport) {
        if(ObjectUtil.isEmpty(userList)||userList.size()==0){
            throw new ApiException("导入用户数据不能为空");
        }
        int successNum=0;
        int failureNum=0;
        StringBuilder successMsg=new StringBuilder();
        StringBuilder failureMsg=new StringBuilder();
        String password=configService.getConfigByKey("sys.user.initPassword");
        for(SysUser user:userList){
            try {
                SysUser u = baseMapper.getUserByUsername(user.getUsername());
                if (ObjectUtil.isNull(u)) {
                    BeanValidators.validateWithException(validator, user);
                    user.setPassword(JwtTokenUtil.md5Encode(user.getUsername() + password));
                    user.setCreateBy("");
                    save(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUsername() + " 导入成功");
                } else if (isUpdateSupport) {
                    BeanValidators.validateWithException(validator, user);
                    checkUserAllowed(u);
                    checkUserDataScope(u.getId());
                    user.setId(u.getId());
                    user.setUpdateBy("");
                    updateById(user);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、账号 " + user.getUsername() + " 更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、账号 " + user.getUsername() + " 已存在");
                }
            }catch (Exception e){
                failureNum++;
                String msg = "<br/>" + failureNum + "、账号 " + user.getUsername() + " 导入失败:";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0){
            failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
            throw new ApiException(failureMsg.toString());
        }else{
            successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
        }
        return successMsg.toString();
    }
    @Override
    public boolean changeUserStatus(SysUser user) {
        checkUserAllowed(user);
        checkUserDataScope(user.getId());
        return updateById(user);
    }
    @Override
    public boolean changeApprove(SysUser user) {
        checkUserAllowed(user);
        checkUserDataScope(user.getId());
        return updateById(user);
    }
}
assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java
对比新文件
@@ -0,0 +1,42 @@
package com.gkhy.assess.system.utils;
import cn.hutool.core.util.ObjectUtil;
import com.gkhy.assess.system.domain.SysUser;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.BeanUtils;
public class ShiroUtils {
    public static Subject getSubject()
    {
        return SecurityUtils.getSubject();
    }
    public static String getIp()
    {
        String host=getSubject().getSession().getHost();
        if(StringUtils.isEmpty(host)){
            return "";
        }
        return host.substring(0,host.length()>=128?128:host.length());
    }
    public static Long getUserId()
    {
        return getSysUser().getId().longValue();
    }
    public static SysUser getSysUser()
    {
        SysUser user = null;
        Object obj = getSubject().getPrincipal();
        if (ObjectUtil.isNotNull(obj))
        {
            user = new SysUser();
            BeanUtils.copyProperties(obj, user);
        }
        return user;
    }
}
assess-system/src/main/resources/mapper/system/SysAgencyMapper.xml
对比新文件
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysAgencyMapper">
    <sql id="selectAgencyVo">
        select a.id,a.name,a.credit_code,a.attribute,a.city,a.district,a.address,a.web,a.legal_person,a.legal_phone,a.manager,a.manager_phone,a.cert_number,a.issue_date,a.valid_date,a.asset_value,a.work_area,a.archive_area,a.reg_address,a.business,a.report_path,a.del_flag,a.create_time,a.remark
        from sys_agency a
    </sql>
    <select id="checkAgencyNameUnique" resultType="com.gkhy.assess.system.domain.SysAgency">
        select id,name from sys_agency where name=#{name} and del_flag=0 limit 1
    </select>
    <select id="agencyList" resultType="com.gkhy.assess.system.domain.SysAgency">
        select a.id,a.name,a.create_time,a.business,a.city from sys_agency a
        <where>
            and a.del_flag = 0
            <if test="name != null and name != ''">
                AND a.name like concat('%', #{name}, '%')
            </if>
            <if test="city != null and city != ''">
                AND a.city=#{city}
            </if>
            <if test="business != null and business != ''">
                AND a.business=#{business}
            </if>
        </where>
        order by a.create_time desc
    </select>
    <select id="getAgencyById" resultType="com.gkhy.assess.system.domain.SysAgency">
        <include refid="selectAgencyVo"/>
        where a.del_flag = 0 and a.id=#{agencyId}
    </select>
    <delete id="deleteAgencyById" parameterType="java.lang.Long">
        update sys_agency set del_flag=1 where id=#{agencyId}
    </delete>
</mapper>
assess-system/src/main/resources/mapper/system/SysAttachMapper.xml
对比新文件
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysAttachMapper">
</mapper>
assess-system/src/main/resources/mapper/system/SysConfigMapper.xml
对比新文件
@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysConfigMapper">
    <resultMap type="com.gkhy.assess.system.domain.SysConfig" id="SysConfigResult">
        <id     property="id"      column="id"      />
        <result property="name"    column="name"    />
        <result property="configKey"     column="config_key"     />
        <result property="configValue"   column="config_value"   />
        <result property="type"    column="type"    />
        <result property="createBy"      column="create_by"      />
        <result property="createTime"    column="create_time"    />
        <result property="updateBy"      column="update_by"      />
        <result property="updateTime"    column="update_time"    />
    </resultMap>
    <sql id="selectConfigVo">
        select id, name, config_key, config_value, type, create_by, create_time, update_by, update_time, remark
        from sys_config
    </sql>
    <!-- 查询条件 -->
    <sql id="sqlwhereSearch">
        <where>
            <if test="id !=null">
                and id = #{id}
            </if>
            <if test="configKey !=null and configKey != ''">
                and config_key = #{configKey}
            </if>
        </where>
    </sql>
    <select id="getConfig" resultMap="SysConfigResult">
        <include refid="selectConfigVo"></include>
        <include refid="sqlwhereSearch"></include>
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysDictDataMapper.xml
对比新文件
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysDictDataMapper">
    <sql id="selectDictDataVo">
        select d.id, d.sort, d.label, d.value, d.dict_type,d.is_default, d.status, d.create_time, d.remark
        from sys_dict_data d
    </sql>
    <update id="updateDictDataDictType">
        update sys_dict_data set dict_type = #{newDictType} where dict_type = #{oldDictType}
    </update>
    <select id="countDictDataByType" resultType="java.lang.Integer">
        select count(1) from sys_dict_data where dict_type=#{dictType}
    </select>
    <select id="getDictDataByType" resultType="com.gkhy.assess.system.domain.SysDictData">
        <include refid="selectDictDataVo"/>
        where d.dict_type=#{dictType} and d.status=0
        order by d.sort asc
    </select>
    <select id="getDictDataById" resultType="com.gkhy.assess.system.domain.SysDictData">
        <include refid="selectDictDataVo"/>
        where d.id=#{dictId}
    </select>
    <select id="dictDataList" resultType="com.gkhy.assess.system.domain.SysDictData">
        <include refid="selectDictDataVo"/>
        <where>
            <if test="dictType != null and dictType != ''">
                AND dict_type = #{dictType}
            </if>
            <if test="label != null and label != ''">
                AND label like concat('%', #{label}, '%')
            </if>
            <if test="status != null and status != ''">
                AND status = #{status}
            </if>
        </where>
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysDictTypeMapper.xml
对比新文件
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysDictTypeMapper">
    <sql id="selectDictTypeVo">
        select d.id,d.name,d.dict_type,d.status,d.create_time,d.remark
        from sys_dict_type d
    </sql>
    <select id="dictTypeList" resultType="com.gkhy.assess.system.domain.SysDictType">
        <include refid="selectDictTypeVo"/>
        <where>
            <if test="name != null and name != ''">
                AND d.name like concat('%', #{name}, '%')
            </if>
            <if test="status != null and status != ''">
                AND d.status = #{status}
            </if>
            <if test="dictType != null and dictType != ''">
                AND d.dict_type like concat('%', #{dictType}, '%')
            </if>
        </where>
    </select>
    <select id="getDictTypeById" resultType="com.gkhy.assess.system.domain.SysDictType">
        <include refid="selectDictTypeVo"/>
        where d.id=#{dictId}
    </select>
    <select id="checkDictTypeUnique" resultType="com.gkhy.assess.system.domain.SysDictType">
        <include refid="selectDictTypeVo"/>
        where d.dict_type = #{dictType} limit 1
    </select>
    <select id="getDictTypeByType" resultType="com.gkhy.assess.system.domain.SysDictType">
        <include refid="selectDictTypeVo"/>
        where d.dict_type = #{dictType}
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysLawMapper.xml
对比新文件
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysLawMapper">
    <sql id="selectLawVo">
        select l.id,l.title,l.sub_title,l.content,l.law_type,l.pub_agency,l.pub_date,l.status,l.create_time,l.remark
        from sys_law l
    </sql>
    <select id="lawList" resultType="com.gkhy.assess.system.domain.SysLaw">
        select l.id,l.title,l.create_time from sys_law l
        <where>
            <if test="title != null and title != ''">
                AND l.title like concat('%', #{title}, '%')
            </if>
            <if test="status != null and status != ''">
                AND l.status = #{status}
            </if>
        </where>
        order by l.create_time desc
    </select>
    <select id="getLawById" resultType="com.gkhy.assess.system.domain.SysLaw">
        <include refid="selectLawVo"/>
        where l.id=#{lawId}
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysNoticeMapper.xml
对比新文件
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysNoticeMapper">
    <sql id="selectNoticeVo">
        select n.id,n.title,n.content,n.status,n.create_time,n.remark
        from sys_notice n
    </sql>
    <select id="noticeList" resultType="com.gkhy.assess.system.domain.SysNotice">
        select n.id,n.title,n.create_time from sys_notice n
        <where>
            <if test="title != null and title != ''">
                AND n.title like concat('%', #{title}, '%')
            </if>
            <if test="status != null and status != ''">
                AND n.status = #{status}
            </if>
        </where>
        order by n.create_time desc
    </select>
    <select id="getNoticeById" resultType="com.gkhy.assess.system.domain.SysNotice">
        <include refid="selectNoticeVo"/>
        where n.id=#{noticeId}
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysRegionMapper.xml
对比新文件
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysRegionMapper">
    <select id="checkRegionUnique" resultType="com.gkhy.assess.system.domain.SysRegion">
        select * from sys_region where name=#{name} and parent_id=#{parentId}
    </select>
</mapper>
assess-system/src/main/resources/mapper/system/SysUserMapper.xml
对比新文件
@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gkhy.assess.system.mapper.SysUserMapper">
    <resultMap type="com.gkhy.assess.system.domain.SysUser" id="SysUserResult">
        <id     property="id"        column="id"         />
        <result property="username"     column="username"      />
        <result property="name"      column="name"       />
        <result property="identity"      column="identity"       />
        <result property="userType"      column="user_type"       />
        <result property="email"         column="email"           />
        <result property="phone"   column="phone"     />
        <result property="sex"           column="sex"             />
        <result property="avatar"        column="avatar"          />
        <result property="password"      column="password"        />
        <result property="salt"          column="salt"            />
        <result property="status"        column="status"          />
        <result property="delFlag"       column="del_flag"        />
        <result property="manageRegion"       column="manage_region"        />
        <result property="agencyId"        column="agency_id"         />
        <result property="post"        column="post"         />
        <result property="expertType"        column="expert_type"         />
        <result property="jobTitle"        column="job_title"         />
        <result property="major"        column="major"         />
        <result property="approve"        column="approve"         />
        <result property="loginIp"       column="login_ip"        />
        <result property="loginDate"     column="login_date"      />
        <result property="pwdUpdateDate" column="pwd_update_date" />
        <result property="createBy"      column="create_by"       />
        <result property="createTime"    column="create_time"     />
        <result property="updateBy"      column="update_by"       />
        <result property="updateTime"    column="update_time"     />
        <result property="remark"        column="remark"          />
        <association property="agency" javaType="com.gkhy.assess.system.domain.SysAgency" resultMap="agencyResult" />
        <collection property="socialAttach" ofType="com.gkhy.assess.system.domain.SysAttach" select="getAttachByUserId" column="{userId=id}"/>
        <collection property="medicalAttach" ofType="com.gkhy.assess.system.domain.SysAttach" select="getAttachByUserId" column="{userId=id}"/>
        <collection property="salaryAttach" ofType="com.gkhy.assess.system.domain.SysAttach" select="getAttachByUserId" column="{userId=id}"/>
    </resultMap>
    <resultMap id="agencyResult" type="com.gkhy.assess.system.domain.SysAgency">
        <id     property="id"       column="agency_id"        />
        <result property="name"     column="agency_name"      />
        <result property="creditCode"      column="credit_code"       />
    </resultMap>
    <sql id="selectUserVo">
        select u.id,u.username, u.name,u.identity,u.user_type,u.phone,u.sex,u.status,u.del_flag,u.manage_region,u.expert_type,u.agency_id,u.post,u.job_title,u.major,u.approve,u.create_time,u.remark,a.id as agency_id,a.name as agency_name,a.credit_code
        from sys_user u
        left join sys_agency a on u.agency_id=a.id
    </sql>
    <delete id="deleteUserById" parameterType="java.lang.Long">
        update sys_user set del_flag=1 where id=#{userId}
    </delete>
    <delete id="deleteUserByIds">
        update sys_user set del_flag = 1 where id in
        <foreach collection="userIds" item="userId" open="(" separator="," close=")">
            #{userId}
        </foreach>
    </delete>
    <select id="getUserByUsername" resultMap="SysUserResult">
        select id,username,name,password,salt,status,del_flag from sys_user
        where username=#{username} and del_flag=0
    </select>
    <select id="monitorList"  resultType="com.gkhy.assess.system.domain.SysUser">
        <include refid="selectUserVo"/>
        <where>
            and u.del_flag = 0 and u.user_type=0
            <if test="username != null and username != ''">
                AND u.username like concat('%', #{username}, '%')
            </if>
            <if test="status != null and status != ''">
                AND u.status = #{status}
            </if>
            <if test="phone != null and phone != ''">
                AND u.phone like concat('%', #{phone}, '%')
            </if>
        </where>
        order by u.create_time desc
    </select>
    <select id="agencyList"  resultMap="SysUserResult">
        <include refid="selectUserVo"/>
        <where>
            and u.del_flag = 0 and u.user_type=1
            <if test="username != null and username != ''">
                AND u.username like concat('%', #{username}, '%')
            </if>
            <if test="status != null and status != ''">
                AND u.status = #{status}
            </if>
            <if test="phone != null and phone != ''">
                AND u.phone like concat('%', #{phone}, '%')
            </if>
        </where>
        order by u.create_time desc
    </select>
    <select id="expertList"  resultMap="SysUserResult">
        <include refid="selectUserVo"/>
        <where>
            and u.del_flag = 0 and u.user_type=2
            <if test="username != null and username != ''">
                AND u.username like concat('%', #{username}, '%')
            </if>
            <if test="status != null and status != ''">
                AND u.status = #{status}
            </if>
            <if test="phone != null and phone != ''">
                AND u.phone like concat('%', #{phone}, '%')
            </if>
        </where>
        order by u.create_time desc
    </select>
    <select id="getUserByPhone" resultMap="SysUserResult">
        select id,username,name,password,salt,status,del_flag from sys_user
        where phone=#{phone} and del_flag=0
    </select>
    <select id="getUserByEmail" resultMap="SysUserResult">
        select id,username,name,password,salt,status,del_flag from sys_user
        where email=#{email} and del_flag=0
    </select>
    <select id="getUserById" resultMap="SysUserResult">
        select id,username,name,password,salt,status,del_flag from sys_user
        where id=#{userId}
    </select>
    <select id="checkLoginNameUnique" resultType="com.gkhy.assess.system.domain.SysUser">
        select id,username from sys_user where username=#{username} and del_flag=0 limit 1
    </select>
    <select id="checkPhoneUnique" resultType="com.gkhy.assess.system.domain.SysUser">
        select id,phone from sys_user where phone=#{phone} and del_flag=0 limit 1
    </select>
    <select id="checkEmailUnique" resultType="com.gkhy.assess.system.domain.SysUser">
        select id,email from sys_user where email=#{email} and del_flag=0 limit 1
    </select>
    <select id="getUserByUsernamePhone" resultType="com.gkhy.assess.system.domain.SysUser">
        select id,username,name,password,salt,status,del_flag from sys_user
        where (username=#{username} or phone=#{username}) and del_flag=0
    </select>
    <select id="getAttachByUserId" resultType="com.gkhy.assess.system.domain.SysAttach">
        select id,name,path,type,user_id,create_time from sys_attach where user_id=#{userId} order by create_time desc limit 1
    </select>
</mapper>
assess-system/src/test/java/com/gkhy/system/DemoTest.java
对比新文件
@@ -0,0 +1,11 @@
package com.gkhy.system;
import cn.hutool.core.convert.Convert;
public class DemoTest {
    public static void main(String[] args) {
        String a="1,2,3";
        Long[] ar= Convert.toLongArray(a);
        System.out.println(ar);
    }
}
assess-system/src/test/java/com/gkhy/system/MybatisPlusGenerator.java
对比新文件
@@ -0,0 +1,109 @@
package com.gkhy.system;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class MybatisPlusGenerator {
    public static void main(String[] args) {
        System.out.println(System.getProperty("user.dir"));
        String model="/gkhy-system";
        // 数据库配置
        DataSourceConfig.Builder dataSourceConfigBuilder = new DataSourceConfig
                .Builder("jdbc:mysql://localhost:3306/gkhy" +
                "?useSSL=false&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true"
                , "root", "password");
        FastAutoGenerator.create(dataSourceConfigBuilder)
                // 全局配置
                .globalConfig((scanner, builder) -> {
                    builder.author("kzy")
                            // 覆盖已生成文件
                            .fileOverride()
                            // 指定输出目录
                            .outputDir(System.getProperty("user.dir") +model+ "/src/main/java/")
                            // 开启 swagger 模式
                            .enableSwagger()
                            // 禁止打开输出目录
                            .disableOpenDir()
                            // 时间策略
                            .dateType(DateType.TIME_PACK)
                            // 类注释日期的格式
                            .commentDate("yyyy-MM-dd HH:mm:ss")
                            .build();
                })
                // 包配置
                .packageConfig((scanner, builder) -> {
                    // 父包名
                    builder.parent("com.gkhy")
                            // 模块名
                            .moduleName("system")
                            // Entity 包名
                            .entity("domain")
                            // Service 包名
                            .service("service")
                            //    Service Impl 包名
                            .serviceImpl("service.impl")
                            // Controller 包名
                            .controller("controller")
                            // Mapper 包名
                            .mapper("mapper")
                            // MapperXML 包名
                            .xml("mapper.system")
                            // 路径配置信息
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") +model+ "/src/main/resources/mapper/"));
                })
                //策略配置
                .strategyConfig((scanner, builder) -> {
                    // 增加表匹配(内存过滤),    include 与 exclude 只能配置一项
                    builder.addInclude(getTables(scanner.apply("请输入要生成的表名,多个英文逗号分隔?所有输入 all")))
                            //     增加表排除匹配(内存过滤),    include 与 exclude 只能配置一项
                            // .addExclude(scanner.apply("请输入要忽略的表名,多个英文逗号分隔?"))
                            //     增加过滤表后缀
                            .addTableSuffix("")
                            //     增加过滤表前缀
                            .addTablePrefix("")
                            // service 策略配置
                            .serviceBuilder()
                            //     格式化文件名称
                            .formatServiceFileName("%sService")
                            .formatServiceImplFileName("%sServiceImpl")
                            // 实体策略配置
                            .entityBuilder()
                            // 开启 lombok 模型
                            .enableLombok()
                            // 开启生成实体时生成字段注解
                            .enableTableFieldAnnotation()
                            // controller 策略配置
                            .controllerBuilder()
                            .formatFileName("%sController")
                            // 开启生成@RestController 控制器
                            .enableRestStyle()
                            //     mapper 策略配置
                            .mapperBuilder()
                            .formatMapperFileName("%sMapper")
                            .enableMapperAnnotation()
                            .formatXmlFileName("%sMapper");
                })
                // 使用Freemarker引擎模板,默认的是Velocity引擎模板
                .templateEngine(new FreemarkerTemplateEngine())
                .execute();
    }
    /**
     * 处理 all 情况
     *
     * @param tables
     * @return
     */
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
}
pom.xml
对比新文件
@@ -0,0 +1,190 @@
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.16</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.gkhy.assess</groupId>
    <artifactId>smart_assess</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>smart_assess</name>
    <description>smart assess</description>
    <modules>
        <module>assess-common</module>
        <module>assess-system</module>
        <module>assess-admin</module>
        <module>assess-framework</module>
    </modules>
    <properties>
        <assess.version>0.0.1-SNAPSHOT</assess.version>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <pagehelper.version>1.4.7</pagehelper.version>
        <hutool.version>5.8.9</hutool.version>
        <knife4j.version>2.0.8</knife4j.version>
        <freemarker.version>2.3.31</freemarker.version>
        <shiro.version>1.12.0</shiro.version>
        <shiro-redis.version>3.3.1</shiro-redis.version>
        <druid.version>1.2.14</druid.version>
        <mybatis-plus.version>3.5.1</mybatis-plus.version>
        <mysql-connector.version>8.0.29</mysql-connector.version>
        <java-jwt.version>3.11.0</java-jwt.version>
        <fastjson.version>1.2.76</fastjson.version>
        <caffeine.version>2.9.3</caffeine.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.gkhy.assess</groupId>
                <artifactId>assess-common</artifactId>
                <version>${assess.version}</version>
            </dependency>
            <dependency>
                <groupId>com.gkhy.assess</groupId>
                <artifactId>assess-system</artifactId>
                <version>${assess.version}</version>
            </dependency>
            <dependency>
                <groupId>com.gkhy.assess</groupId>
                <artifactId>assess-framework</artifactId>
                <version>${assess.version}</version>
            </dependency>
            <dependency>
                <groupId>com.gkhy.assess</groupId>
                <artifactId>assess-admin</artifactId>
                <version>${assess.version}</version>
            </dependency>
            <!--MyBatis分页插件-->
            <dependency>
                <groupId>com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>${pagehelper.version}</version>
            </dependency>
            <!--Hutool Java工具包-->
            <dependency>
                <groupId>cn.hutool</groupId>
                <artifactId>hutool-all</artifactId>
                <version>${hutool.version}</version>
            </dependency>
            <!--接口文档生成工具包-->
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>knife4j-spring-boot-starter</artifactId>
                <version>${knife4j.version}</version>
            </dependency>
            <!-- 阿里数据库连接池 -->
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
                <version>${druid.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql-connector.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>${mybatis-plus.version}</version>
            </dependency>
            <dependency>
                <groupId>org.freemarker</groupId>
                <artifactId>freemarker</artifactId>
                <version>${freemarker.version}</version>
            </dependency>
            <!--shiro-->
            <dependency>
                <groupId>org.apache.shiro</groupId>
                <artifactId>shiro-spring-boot-web-starter</artifactId>
                <version>${shiro.version}</version>
            </dependency>
            <dependency>
                <groupId>org.crazycake</groupId>
                <artifactId>shiro-redis</artifactId>
                <version>${shiro-redis.version}</version>
            </dependency>
            <!--JWT(Json Web Token)登录支持-->
            <dependency>
                <groupId>com.auth0</groupId>
                <artifactId>java-jwt</artifactId>
                <version>${java-jwt.version}</version>
            </dependency>
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.ben-manes.caffeine</groupId>
                <artifactId>caffeine</artifactId>
                <version>${caffeine.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter</artifactId>-->
<!--        </dependency>-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
<!--            <plugin>-->
<!--                <groupId>org.springframework.boot</groupId>-->
<!--                <artifactId>spring-boot-maven-plugin</artifactId>-->
<!--            </plugin>-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>