puzhibing
2023-11-28 7b726d5ff439e7b8bb66369ecc5881e370286bc8
更新基础代码
1,328个文件已添加
324164 ■■■■■ 已修改文件
guns-admin/pom.xml 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/GunsApplication.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/GunsServletInitializer.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/EhCacheConfig.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/SpringSessionConfig.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/SwaggerConfig.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/datasource/MultiDataSourceConfig.java 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/datasource/SingleDataSourceConfig.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/properties/BeetlProperties.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/properties/GunsProperties.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/web/BeetlConfig.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/web/ShiroConfig.java 219 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/config/web/WebConfig.java 176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/aop/GlobalExceptionHandler.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/aop/LogAop.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/aop/PermissionAop.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/beetl/BeetlConfiguration.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/beetl/ShiroExt.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/annotion/BussinessLog.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/annotion/Permission.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/Const.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/DatasourceEnum.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/JwtConstants.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/cache/Cache.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/cache/CacheKey.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DeleteDict.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DeptDict.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DictMap.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/LogDict.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/MenuDict.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/NoticeMap.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/RoleDict.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/UserDict.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/base/AbstractDictMap.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/base/SystemDict.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/factory/DictFieldWarpperFactory.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/ConstantFactory.java 345 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/IConstantFactory.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/MutiStrFactory.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/PageFactory.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/BizLogType.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/ExpenseState.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/LogSucceed.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/LogType.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/ManagerStatus.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/MenuOpenStatus.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/MenuStatus.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/Order.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/InvalidKaptchaException.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/GunsUserFilter.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/RestApiInteceptor.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/SessionHolderInterceptor.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/listener/ConfigListener.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/log/LogManager.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/log/LogObjectHolder.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/log/factory/LogFactory.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/log/factory/LogTaskFactory.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroDbRealm.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroKit.java 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroUser.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/ICheck.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/PermissionCheckFactory.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/PermissionCheckManager.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/factory/IShiro.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/factory/ShiroFactroy.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/tag/DictSelectorTag.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/util/ApiMenuFilter.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/util/Contrast.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/util/JwtTokenUtil.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/core/util/KaptchaUtil.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/ApiController.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/AppUserController.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/BannerController.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/EncyclopedicKnowledgeController.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/HouseResourceController.java 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/HousingDemandController.java 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/api/RegionController.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/code/controller/CodeController.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/code/factory/DefaultTemplateFactory.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/code/service/TableService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/DeptController.java 172 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/DictController.java 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/KaptchaController.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/LoginController.java 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/LoginLogController.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/MenuController.java 249 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/NoticeController.java 145 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/RoleController.java 236 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/SysRegionController.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/UEditorController.java 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/UserMgrController.java 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/AppUserMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/BannerMapper.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CollectionHouseResourceMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CollectionHousingDemandMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/DeptMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/DictMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/EncyclopedicKnowledgeMapper.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/EncyclopedicKnowledgeUpvoteMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ExpenseMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HouseResourceMapper.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HouseTypeMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HousingDemandDistrictMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HousingDemandMapper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/LoginLogMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/MenuMapper.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/NoticeMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/OperationLogMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RegionMapper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RelationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ReportHouseResourceMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ReportHousingDemandMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RoleMapper.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/SearchHistoryConditionMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/SysDataTypeMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/UserMapper.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/AppUserMapper.xml 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/BannerMapper.xml 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CollectionHouseResourceMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CollectionHousingDemandMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/DeptMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/DictMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/EncyclopedicKnowledgeMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/EncyclopedicKnowledgeUpvoteMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ExpenseMapper.xml 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HouseResourceMapper.xml 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HouseTypeMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HousingDemandDistrictMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HousingDemandMapper.xml 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/LoginLogMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/MenuMapper.xml 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/NoticeMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/OperationLogMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RegionMapper.xml 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RelationMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReportHouseResourceMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReportHousingDemandMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RoleMapper.xml 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/SearchHistoryConditionMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/SysDataTypeMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/UserMapper.xml 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/factory/UserFactory.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/AppUser.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Banner.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CollectionHouseResource.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CollectionHousingDemand.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Dept.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Dict.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/EncyclopedicKnowledge.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/EncyclopedicKnowledgeUpvote.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Expense.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HouseResource.java 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HouseType.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HousingDemand.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HousingDemandDistrict.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/LoginLog.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Menu.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Notice.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/OperationLog.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Region.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Relation.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/ReportHouseResource.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/ReportHousingDemand.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Role.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/SearchHistoryCondition.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/SysDataType.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/User.java 246 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IAppUserService.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IBannerService.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ICollectionHouseResourceService.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ICollectionHousingDemandService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IDeptService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IDictService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IEncyclopedicKnowledgeService.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IEncyclopedicKnowledgeUpvoteService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHouseResourceService.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHouseTypeService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHousingDemandDistrictService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHousingDemandService.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ILoginLogService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IMenuService.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/INoticeService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IOperationLogService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRegionService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRelationService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReportHouseResourceService.java 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReportHousingDemandService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRoleService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ISearchHistoryConditionService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ISysDataTypeService.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IUserService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/AppUserServiceImpl.java 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BannerServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/CollectionHouseResourceServiceImpl.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/CollectionHousingDemandServiceImpl.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DeptServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DictServiceImpl.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/EncyclopedicKnowledgeServiceImpl.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/EncyclopedicKnowledgeUpvoteServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HouseResourceService.java 300 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HouseTypeServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HousingDemandDistrictServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HousingDemandServiceImpl.java 272 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/LoginLogServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/MenuServiceImpl.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/NoticeServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OperationLogServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RegionServiceImpl.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RelationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReportHouseResourceServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReportHousingDemandServiceImpl.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RoleServiceImpl.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SearchHistoryConditionServiceImpl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SysDataTypeServiceImpl.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/UserServiceImpl.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ManagerUser.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ReqAddManager.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ReqEditManager.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/UserDto.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/AESUtil.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/DataUtil.java 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmptyUtil.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/ExcelUtil.java 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDMapGeocodingUtil.java 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GeodesyUtil.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/HttpRequestUtil.java 184 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/MD5AndKL.java 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/QRCode/QRCodeUtils.java 268 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java 245 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/ResultUtil.java 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SinataUtil.java 388 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SmsUtil.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SpringUtil.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SysException.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/TencentMapUtil.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/UUIDUtil.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthIntercepter.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthService.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthenticationKit.java 259 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/Configuration.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/HMACSHA1.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/HashKit.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/UrlEncoderUtils.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/httpClinet/HttpClientUtil.java 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/httpClinet/HttpResult.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/AES.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/AesException.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/ByteGroup.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/PKCS7Encoder.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/SHA1.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/SubscribeMessageUtil.java 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WXBizMsgCrypt.java 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WXCore.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WeChatUtil.java 435 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WxPKCS7Encoder.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/XMLParse.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/Category.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/KeywordEnum.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/MessageTemplate.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/PubTemplateKeywords.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/PubTemplatetitles.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/DeptWarpper.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/DictWarpper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/LogWarpper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/MenuWarpper.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/NoticeWrapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/PointLocation.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/RoleWarpper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/UserWarpper.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/HousingDemandReq.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/RegisterAccountReq.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/ReportHouseResourceReq.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/ReportHousingDemandReq.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/SearchHouseResourceReq.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/SearchHousingDemandReq.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/AppletLoginRes.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/BannerRes.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/ContactInformationRes.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/DistrictHouseResourceNumberRes.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/DistrictRes.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/EncyclopedicKnowledgeInfoRes.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/EncyclopedicKnowledgeRes.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/HouseResourceInfoRes.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/HousingDemandInfoRes.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHouseResourceListRes.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHouseResourceRes.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHousingDemandListRes.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHousingDemandRes.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/META-INF/spring-devtools.properties 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/application-dev.yml 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/application-produce.yml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/application.yml 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/ehcache.xml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/resources/logback-spring.xml 222 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/404.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/blackboard.html 771 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/code/code.html 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/_container.html 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/_right.html 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/_tab.html 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/_theme.html 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/NameCon.tag 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/SelectCon.tag 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/TimeCon.tag 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/avatar.tag 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/button.tag 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/input.tag 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/select.tag 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/table.tag 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/tag_tips 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/common/tags/uploadImg.tag 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/index.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/login.html 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/appUser/appUser.html 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner.html 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_add.html 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_edit.html 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_info.html 209 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/banner/clickBannerUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/code/code.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/coupon/clickBannerUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon.html 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_add.html 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_edit.html 270 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_info.html 191 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/clickUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity.html 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_add.html 480 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_edit.html 486 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_info.html 369 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_add.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_edit.html 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_add.html 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_edit.html 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/exposureCrowd/exposureCrowd.html 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStation/gasStation.html 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity.html 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_add.html 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_edit.html 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_gasStation.html 152 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_iconSet.html 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/goods/goods.html 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/html/html.html 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/icon/clickIconUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon.html 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_add.html 274 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_edit.html 278 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_info.html 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/log/log.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/log/login_log.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_add.html 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_edit.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_add.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_edit.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/oilPrice/oilPrice.html 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/clickPointActivityUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity.html 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity_add.html 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity_edit.html 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/prizeList.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/receivePrizeList.html 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/taskList.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/role/role.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/role/role_add.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/role/role_assign.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/role/role_edit.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/clickSalesPromotionUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice_edit.html 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice_iconSet.html 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion.html 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_add.html 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_edit.html 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_info.html 132 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_mainInfo.html 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings_add.html 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings_edit.html 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/constant.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponActivityInfo.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponActivityStatistics.html 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponPayStatistics.html 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponStatistics.html 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/downgrade.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/equityDetails.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/pageViewsStatistics.html 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/pointActivityStatistics.html 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/salesPromotionStatistics.html 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/taskStatistics.html 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/upgrade.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/vipLevelNumberSummaryGraph.html 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/statistics/vipLevelStatistics.html 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/subscribeMessage/subscribeMessage.html 139 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/subscribeMessage/subscribeMessageUser.html 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/sysOperationLog/sysOperationLog.html 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/backConfigure.html 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/homeSystemConfigure.html 180 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/phoneSystemConfigure.html 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/shareApplets.html 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/signSystemConfigure.html 137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/vipCycle.html 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/task/clickTaskUserList.html 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/task/task.html 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/task/task_add.html 199 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/task/task_edit.html 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/task/task_info.html 159 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user.html 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user_add.html 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user_chpwd.html 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user_edit.html 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user_roleassign.html 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/user/user_view.html 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/viewSubCodes.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel.html 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannelStatistics.html 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannelStatisticsInfo.html 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel_add.html 178 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel_edit.html 181 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipGrowthRules/vipGrowthRules.html 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction.html 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction_add.html 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction_edit.html 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/system/vipLevel/vipLevel.html 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/WEB-INF/view/updatePass.html 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.css 458 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.min.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.js 3144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.min.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.min.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.js 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.js 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.js.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/_fstyle.css 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/bootstrap-rtl.css 1468 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/bootstrap.min.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/font-awesome.css 2026 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/font-awesome.min.css 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/login.css 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-1.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-3.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/patterns/header-profile.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/patterns/shattered.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/bootstrap-table/bootstrap-table.min.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/bootstrap-treetable/bootstrap-treetable.css 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/chosen/chosen.css 423 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/iCheck/custom.css 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/iCheck/green.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/iCheck/green@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/images/sprite-skin-flat.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/validate/bootstrapValidator.min.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/webuploader/webuploader.css 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/demo.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_close.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_open.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/2.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/3.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/4.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/5.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/6.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/7.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/8.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/9.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/line_conn.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/loading.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/plugins/ztree/zTreeStyle.css 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/css/style.css 7897 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/excel/公告导入模板.xlsx 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/FontAwesome.otf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.svg 640 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff2 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.svg 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/1@3x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/20211230154035.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/NoPIC.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/backgroundImg.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/boy.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/girl.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/loading-upload.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/locked.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/logo.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/logo1.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/shangchuanpic.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/signTypeOne.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/signTypeTwo.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/user.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/img/yuansu.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/Avatar@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/add.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/coupon-bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/pos@x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/subtract.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/imge/zhekou@x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.css 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.min.css 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.min.css.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.js 2915 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.js.map 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.min.js 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.min.js.map 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/bootstrap.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/DateUtils.js 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/Feng.js 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/ajax-object.js 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/bootstrap-table-object.js 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/select-list-object.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/tree-table-object.js 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/web-upload-image.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/web-upload-object.js 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/common/ztree-object.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/contabs.js 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/content.js 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/hplus.js 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/html2canvas.js 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/jquery.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/jquery.min.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/jquery.qrcode.js 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/jquery.qrcode.min.js 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/layui.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/code.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/laydate/default/laydate.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/icon-ext.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/layer.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-0.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-1.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-2.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/font/iconfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/font/iconfont.svg 554 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/font/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/font/iconfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/font/iconfont.woff2 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/layui/layui.js 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table-mobile.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/bootstrap-treetable/bootstrap-treetable.js 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/chosen/chosen.jquery.js 1211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/iCheck/icheck.min.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/laydate.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.svg 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/laydate.css 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/layer.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/mobile/layer.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/mobile/need/layer.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon-ext.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/layer.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-0.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-1.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-2.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/metisMenu/jquery.metisMenu.js 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/pace/pace.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/slimscroll/jquery.slimscroll.min.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/emotion.css 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/emotion.js 272 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/0.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/bface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/cface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/fface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/jxface2.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/neweditor-tab-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/tface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/wface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/yface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.css 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.html 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/images/formula.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/image.css 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/image.js 445 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/close.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/upload1.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/upload2.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/link/link.js 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/map/map.html 148 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/map/map.js 263 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/center_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/left_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/none_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/right_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/video.css 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/video.js 286 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/index.html 277 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/en.js 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/addimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/alldeletebtnhoverskin.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/alldeletebtnupskin.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/background.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/button.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/deletedisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/deleteenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/imglabel.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/listbackground.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotateleftdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotateleftenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotaterightdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotaterightenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/imglabel.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/zh-cn.js 150 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/css/umeditor.css 777 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/css/umeditor.min.css 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/caret.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/close.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/ok.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/pop-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/spacer.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/videologo.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/jquery.min.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.otf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.svg 5102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/STIXFontLicense2010.txt 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.svg 3318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.svg 1738 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.svg 1137 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.svg 1089 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.css 357 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.js 3888 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.config.js 323 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.js 10927 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.min.js 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/validate/additional-methods.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/validate/bootstrapValidator.min.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/validate/zh_CN.js 370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/wangEditor/wangEditor.js 3967 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/Uploader.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.js 6502 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.fis.js 8083 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.js 4622 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.js 6030 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.js 8106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.min.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.js 5026 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.js 8012 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.min.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.js 4993 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/plugins/ztree/jquery.ztree.all.min.js 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/qrcode.js 1237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/qrcode.min.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/vue.js 12014 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/js/vue.min.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._avatar-vip@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._banner@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._coupon-title@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._guanzhu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._integral-title@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._jifen@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._jilu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._kefu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._qiandao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._renwu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._shangcheng@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._vx@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._xieyi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._yinsi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._youhui@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._youhuiquan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._ziliao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/LV1@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/avatar-vip@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/banner@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/coin-small@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/coin@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/coupon-title@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/coupon-v2@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/coupon@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/customer@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/folllow@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/guanzhu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/huangguan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/integral-title@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/jifen@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/jilu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/jinbi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/jine@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/kefu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/level-bg@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/member-protocol@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/my-coupon@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/order@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/protocol@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/qiandao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/renwu@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/shangcheng@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/task@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/userinfo@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/vx@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/weixin@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/xieyi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/yinsi@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/youhui@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/youhuiquan@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/zhengce@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/mine/mine/ziliao@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/code/gen.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/flowable/expense/expense.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/flowable/expense/expense_info.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/flowable/process/process.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/flowable/process/process_info.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/appUser/appUser.js 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/banner/banner.js 382 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/banner/banner_info.js 567 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/banner/clickBannerUserList.js 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/code/code.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/coupon/clickCouponUserList.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/coupon/coupon.js 515 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/coupon/coupon_info.js 446 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/couponActivity/clickUserList.js 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/couponActivity/couponActivity.js 436 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/couponActivity/couponActivity_info.js 1127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/dept/dept.js 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/dept/dept_info.js 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/dict/dict.js 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/dict/dict_info.js 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/exposureCrowd/exposureCrowd.js 520 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/gasStation/gasStation.js 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity.js 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_gasStation.js 317 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_iconSet.js 240 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_info.js 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/goods/goods.js 262 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/html/html.js 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/icon/clickIconUserList.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/icon/icon.js 360 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/icon/icon_info.js 483 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/log/log.js 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/log/login_log.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/menu/menu.js 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/menu/menu_info.js 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/notice/notice.js 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/notice/notice_info.js 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/oilPrice/oilPrice.js 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/clickPointActivityUserList.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/pointActivity.js 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/pointActivity_info.js 1931 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/prizeList.js 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/receivePrizeList.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/pointActivity/taskList.js 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/role/role.js 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/role/role_info.js 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/clickSalesPromotionUserList.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice.js 188 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice_iconSet.js 235 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice_info.js 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/salesPromotion.js 493 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/salesPromotion/salesPromotion_info.js 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/shareAppletSettings/shareAppletSettings.js 144 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/shareAppletSettings/shareAppletSettings_info.js 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/constant.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/couponActivityInfo.js 117 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/couponActivityStatistics.js 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/couponPayStatistics.js 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/couponStatistics.js 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/downgrade.js 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/equityDetails.js 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/pageViewsStatistics.js 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/pointActivityStatistics.js 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/salesPromotionStatistics.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/taskStatistics.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/upgrade.js 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/vipLevelNumberSummaryGraph.js 163 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/statistics/vipLevelStatistics.js 202 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/subscribeMessage/subscribeMessage.js 553 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/subscribeMessage/subscribeMessageUser.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/sysOperationLog/sysOperationLog.js 124 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/backConfigure.js 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/homeSystemConfigure.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/phoneSystemConfigure.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/shareApplets.js 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/signSystemConfigure.js 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/systemConfigure/vipCycle.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/task/clickTaskUserList.js 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/task/task.js 318 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/task/task_info.js 1316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/user/user.js 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/user/user_info.js 322 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipChannel/viewSubCodes.js 224 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannel.js 221 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannelStatistics.js 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannelStatisticsInfo.js 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannel_info.js 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipGrowthRules/vipGrowthRules.js 518 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipJurisdiction/vipJurisdiction.js 324 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipJurisdiction/vipJurisdiction_info.js 437 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/modular/system/vipLevel/vipLevel.js 403 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/anchor/anchor.html 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.css 681 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.html 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.js 754 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_chm.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_default.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_doc.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_exe.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_jpg.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_mp3.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_mv.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_pdf.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_ppt.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_psd.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_rar.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_txt.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_xls.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/alignicon.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/alignicon.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/file-icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/file-icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/image.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/progress.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/success.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/success.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.css 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.html 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.js 376 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/images/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/images/success.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/chart.config.js 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.css 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.html 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.js 519 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts0.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts1.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts2.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts3.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts4.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts5.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.css 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.html 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.js 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/0.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/bface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/cface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/fface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/jxface2.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/neweditor-tab-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/tface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/wface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/yface.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/gmap/gmap.html 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.css 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.html 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.js 56 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.css 894 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.html 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.js 1142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/alignicon.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/image.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/progress.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/success.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/success.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/insertframe/insertframe.html 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/internal.js 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/link/link.html 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/map/map.html 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/map/show.html 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.css 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.html 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.js 192 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/preview/preview.html 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/addimg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/brush.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/delimg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/delimgH.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/empty.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/emptyH.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/eraser.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/redo.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/redoH.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/scale.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/scaleH.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/size.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/undo.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/undoH.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.css 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.html 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.js 671 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/searchreplace/searchreplace.html 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/searchreplace/searchreplace.js 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/snapscreen/snapscreen.html 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/spechars/spechars.html 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/spechars/spechars.js 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/dragicon.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.css 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.html 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.js 237 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittd.html 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittip.html 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/config.js 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/bg.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre0.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre1.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre2.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre3.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre4.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.css 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.html 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/center_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/file-icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/file-icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/image.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/left_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/none_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/progress.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/right_focus.jpg 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/success.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/success.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.css 635 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.html 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.js 791 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/webapp/webapp.html 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/fClipboard_ueditor.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/imageUploader.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/tangram.js 1495 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/wordimage.html 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/wordimage.js 157 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/index.html 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/jsp/config.json 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/jsp/controller.jsp 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/en.js 684 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/addimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/alldeletebtnhoverskin.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/alldeletebtnupskin.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/background.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/button.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/deletedisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/deleteenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/listbackground.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotateleftdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotateleftenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotaterightdisable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotaterightenable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/copy.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/localimage.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/music.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/zh-cn.js 669 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/css/ueditor.css 1903 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/css/ueditor.min.css 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/dialogbase.css 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/anchor.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow_down.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow_up.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/button-bg.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cancelbutton.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/charts.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_h.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_h.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_v.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_v.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/dialog-title-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/filescan.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/highlighted.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons-all.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/loaderror.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/loading.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/lock.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/neweditor-tab-bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/pagebreak.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/scale.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/sortable.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/spacer.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/sparator_v.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/table-cell-align.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/tangram-colorpicker.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/toolbar_bg.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/unhighlighted.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/upload.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/videologo.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/word.gif 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/wordpaste.png 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/iframe.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/SyntaxHighlighter/shCore.js 3655 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/SyntaxHighlighter/shCoreDefault.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/codemirror/codemirror.css 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/codemirror/codemirror.js 3581 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/mootools-adapter.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/mootools-adapter.src.js 313 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/prototype-adapter.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/prototype-adapter.src.js 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/standalone-framework.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/standalone-framework.src.js 583 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts-more.js 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts-more.src.js 2430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts.js 283 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts.src.js 16974 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/annotations.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/annotations.src.js 401 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/canvas-tools.js 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/canvas-tools.src.js 3113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/data.js 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/data.src.js 582 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/drilldown.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/drilldown.src.js 447 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/exporting.js 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/exporting.src.js 709 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/funnel.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/funnel.src.js 289 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/heatmap.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/heatmap.src.js 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/map.js 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/map.src.js 1002 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/no-data-to-display.js 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/no-data-to-display.src.js 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/dark-blue.js 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/dark-green.js 255 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/gray.js 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/grid.js 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/skies.js 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.js 9789 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.min.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.min.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/snapscreen/UEditorSnapscreen.exe 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.eot 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.svg 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.ttf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.woff 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.css 766 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.min.css 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video.dev.js 7108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video.js 129 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/Uploader.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.custom.js 5670 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.custom.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.flashonly.js 4176 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.flashonly.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.html5only.js 5559 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.html5only.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.js 6733 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.withoutimage.js 4593 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.withoutimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/xss.min.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.js 1256 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.min.js 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.swf 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.all.js 29568 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.all.min.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.config.js 499 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.parse.js 1022 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.parse.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/test/java/com/stylefeng/guns/GunsApplicationTest.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/src/test/sql/test.sql 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/pom.xml 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/CoreFlag.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/aop/BaseControllerExceptionHandler.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/controller/BaseController.java 130 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/controller/GlobalController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/controller/GunsErrorView.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/tips/ErrorTip.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/tips/SuccessTip.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/tips/Tip.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/base/warpper/BaseControllerWarpper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/cache/BaseCacheFactory.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/cache/CacheKit.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/cache/EhcacheFactory.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/cache/ICache.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/cache/ILoader.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultFastjsonConfig.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultMultiConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultProperties.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultWebConfig.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/properties/DruidProperties.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/config/properties/MutiDataSourceProperties.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/constant/IsMenu.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/datascope/DataScope.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/datascope/DataScopeInterceptor.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/db/Db.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/exception/GunsException.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/exception/GunsExceptionEnum.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/exception/ServiceExceptionEnum.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/DataSourceContextHolder.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/DynamicDataSource.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/annotion/DataSource.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/aop/MultiSourceExAop.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/node/MenuNode.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/node/ZTreeNode.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/page/PageBT.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/page/PageInfoBT.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/qr/ImgQrTool.java 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/qr/MatrixToImageConfig.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/qr/MatrixToImageWriter.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/qr/QrImage.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/BasicType.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/BeanKit.java 508 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/ClassKit.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/CollectionKit.java 801 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/DateTime.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/DateTimeKit.java 665 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/HexKit.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/HttpKit.java 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/ObjectKit.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/PageKit.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/StrKit.java 1370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/WafKit.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/WafRequestWrapper.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/support/exception/ToolBoxException.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/Convert.java 1060 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/DateUtil.java 329 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/FileUtil.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/HttpSessionHolder.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/IdGenerator.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/MD5Util.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/NumUtil.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/PingYinUtil.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/RenderUtil.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/ResKit.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/SimpleContrast.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/SpringContextHolder.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/SqlUtil.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/util/ToolUtil.java 582 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/xss/XssFilter.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/java/com/stylefeng/guns/core/xss/XssHttpServletRequestWrapper.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/resources/META-INF/spring.factories 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-core/src/main/resources/default-config.properties 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/action/GunsCodeGenerator.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/AbstractGeneratorConfig.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/GunsGeneratorConfig.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/WebGeneratorConfig.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/action/model/GenQo.java 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/SimpleTemplateEngine.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/base/AbstractTemplateEngine.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/base/GunsTemplateEngine.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ContextConfig.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ControllerConfig.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/DaoConfig.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/Menu.java 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/PageConfig.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ServiceConfig.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/SqlConfig.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/Controller.java.btl 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/page.html.btl 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/page.js.btl 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/page_add.html.btl 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/page_edit.html.btl 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-generator/src/main/resources/gunsTemplate/advanced/page_info.js.btl 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
rental_house_applet.sql 614 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
guns-admin/pom.xml
New file
@@ -0,0 +1,317 @@
<?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.stylefeng</groupId>
        <artifactId>guns-parent</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>guns-admin</artifactId>
    <name>guns-admin</name>
    <description>guns 的spring boot版本</description>
    <packaging>war</packaging>
    <dependencies>
        <dependency>
            <groupId>com.stylefeng</groupId>
            <artifactId>guns-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.stylefeng</groupId>
            <artifactId>guns-generator</artifactId>
        </dependency>
        <!--spring boot依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--shiro依赖-->
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-core</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-spring</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.shiro</groupId>
            <artifactId>shiro-ehcache</artifactId>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.ehcache</groupId>
            <artifactId>ehcache</artifactId>
        </dependency>
        <!--需要分布式session的话需要放开注释-->
        <!--<dependency>-->
        <!--<groupId>org.springframework.session</groupId>-->
        <!--<artifactId>spring-session-data-redis</artifactId>-->
        <!--</dependency>-->
        <!--<dependency>-->
        <!--<groupId>org.springframework.boot</groupId>-->
        <!--<artifactId>spring-boot-starter-data-redis</artifactId>-->
        <!--</dependency>-->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.ibeetl</groupId>
            <artifactId>beetl</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
        </dependency>
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>jwks-rsa</artifactId>
            <version>0.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.8.10.ALL</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <!-- 导入Excel数据依赖 start -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>5.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>5.0.0</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.2</version>
        </dependency>
        <!-- 计算两坐标间的直线距离 -->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
        <!--百度UEditor-->
        <dependency>
            <groupId>com.gitee.qdbp.thirdparty</groupId>
            <artifactId>ueditor</artifactId>
            <version>1.4.3.3</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.9</version>
        </dependency>
        <dependency>
            <!-- jsoup HTML parser library @ https://jsoup.org/ -->
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.13.1</version>
        </dependency>
        <!--<dependency>-->
            <!--<groupId>org.bouncycastle</groupId>-->
            <!--<artifactId>bcprov-jdk16</artifactId>-->
            <!--<version>1.46</version>-->
        <!--</dependency>-->
        <!--二维码-->
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>core</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.google.zxing</groupId>
            <artifactId>javase</artifactId>
            <version>3.3.0</version>
        </dependency>
        <dependency>
            <groupId>com.vdurmont</groupId>
            <artifactId>emoji-java</artifactId>
            <version>5.1.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>
    <build>
        <!--打包jar包方式-->
        <!--<plugins>-->
            <!--<plugin>-->
                <!--<groupId>org.springframework.boot</groupId>-->
                <!--<artifactId>spring-boot-maven-plugin</artifactId>-->
                <!--<configuration>-->
                    <!--<fork>true</fork>&lt;!&ndash; 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart &ndash;&gt;-->
                <!--</configuration>-->
            <!--</plugin>-->
        <!--</plugins>-->
        <!--打包war包引入本地jar的打包方式-->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <!-- 设置成false,否则检查web.xml是否存在。因为springboot是没有web.xml的 -->
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                    <!--打包后的项目名-->
                    <!--<warName>example</warName>-->
                    <webResources>
                        <resource>
                            <!--把本地lib里面的jar复制到lib-->
                            <directory>${project.basedir}/lib</directory>
                            <targetPath>WEB-INF/lib/</targetPath>
                            <includes>
                                <include>**/*.jar</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/webapp</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>lib</directory>
                <targetPath>BOOT-INF/lib/</targetPath>
                <includes>
                    <include>**/*.jar</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>
guns-admin/src/main/java/com/stylefeng/guns/GunsApplication.java
New file
@@ -0,0 +1,55 @@
package com.stylefeng.guns;
import org.apache.http.client.HttpClient;
import org.apache.http.config.SocketConfig;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
/**
 * SpringBoot方式启动类
 *
 * @author stylefeng
 * @Date 2017/5/21 12:06
 */
@EnableScheduling
@SpringBootApplication
@EnableTransactionManagement//启动事务功能
public class GunsApplication {
    private final static Logger logger = LoggerFactory.getLogger(GunsApplication.class);
    public static void main(String[] args) {
        SpringApplication.run(GunsApplication.class, args);
        logger.info("GunsApplication is success!");
    }
    @Bean //通过ip地址调用
    public RestTemplate restTemplate() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        connectionManager.setDefaultSocketConfig(SocketConfig.custom().setTcpNoDelay(true).build());
        connectionManager.setDefaultMaxPerRoute(100);//最大并发连接
        connectionManager.setMaxTotal(200); // 总的最大连接数
        HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).build();
        HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
        httpRequestFactory.setConnectionRequestTimeout(30 * 1000);
        httpRequestFactory.setConnectTimeout(1000 * 60 * 5);
        httpRequestFactory.setReadTimeout(30 * 3000);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/GunsServletInitializer.java
New file
@@ -0,0 +1,18 @@
package com.stylefeng.guns;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/**
 * Guns Web程序启动类
 *
 * @author fengshuonan
 * @date 2017-05-21 9:43
 */
public class GunsServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(GunsApplication.class);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/EhCacheConfig.java
New file
@@ -0,0 +1,39 @@
package com.stylefeng.guns.config;
import net.sf.ehcache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
/**
 * ehcache配置
 *
 * @author fengshuonan
 * @date 2017-05-20 23:11
 */
@Configuration
@EnableCaching
public class EhCacheConfig {
    /**
     * EhCache的配置
     */
    @Bean
    public EhCacheCacheManager cacheManager(CacheManager cacheManager) {
        return new EhCacheCacheManager(cacheManager);
    }
    /**
     * EhCache的配置
     */
    @Bean
    public EhCacheManagerFactoryBean ehcache() {
        EhCacheManagerFactoryBean ehCacheManagerFactoryBean = new EhCacheManagerFactoryBean();
        ehCacheManagerFactoryBean.setConfigLocation(new ClassPathResource("ehcache.xml"));
        ehCacheManagerFactoryBean.setShared(true);//共享缓存,避免tomcat启动报错
        return ehCacheManagerFactoryBean;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/RedisConfig.java
New file
@@ -0,0 +1,45 @@
package com.stylefeng.guns.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Component
public class RedisConfig {
    @Value("${redis.host}")
    private String host;
    @Value("${redis.port}")
    private int port;
    @Value("${redis.timeout}")
    private int timeout;
    @Value("${redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${redis.jedis.pool.max-wait}")
    private long maxWaitMillis;
    @Value("${redis.password}")
    private String password;
    @Value("${redis.block-when-exhausted}")
    private boolean  blockWhenExhausted;
    @Bean
    public JedisPool redisPoolFactory()  throws Exception{
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
        // 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
        jedisPoolConfig.setBlockWhenExhausted(blockWhenExhausted);
        // 是否启用pool的jmx管理功能, 默认true
        jedisPoolConfig.setJmxEnabled(true);
        JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
        return jedisPool;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/SpringSessionConfig.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
/**
 * spring session配置
 *
 * @author fengshuonan
 * @date 2017-07-13 21:05
 */
//@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800)  //session过期时间  如果部署多机环境,需要打开注释
@ConditionalOnProperty(prefix = "guns", name = "spring-session-open", havingValue = "true")
public class SpringSessionConfig {
}
guns-admin/src/main/java/com/stylefeng/guns/config/SwaggerConfig.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.config;
import io.swagger.annotations.ApiOperation;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
 * swagger配置类
 *
 * @author fengshuonan
 * @date 2017年6月1日19:42:59
 */
@Configuration
@EnableSwagger2
@ConditionalOnProperty(prefix = "guns", name = "swagger-open", havingValue = "true")
public class SwaggerConfig{
    @Bean
    public Docket createRestApi() {
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))                         //这里采用包含注解的方式来确定要显示的接口
                //.apis(RequestHandlerSelectors.basePackage("com.stylefeng.guns.modular.system.controller"))    //这里采用包扫描的方式来确定要显示的接口
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Guns Doc")
                .description("Guns Api文档")
                .termsOfServiceUrl("http://git.oschina.net/naan1993/guns")
                .contact("stylefeng")
                .version("2.0")
                .build();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/datasource/MultiDataSourceConfig.java
New file
@@ -0,0 +1,124 @@
package com.stylefeng.guns.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.stylefeng.guns.core.config.properties.DruidProperties;
import com.stylefeng.guns.core.config.properties.MutiDataSourceProperties;
import com.stylefeng.guns.core.datascope.DataScopeInterceptor;
import com.stylefeng.guns.core.mutidatasource.DynamicDataSource;
import com.stylefeng.guns.core.mutidatasource.aop.MultiSourceExAop;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.sql.SQLException;
import java.util.HashMap;
/**
 * 多数据源配置<br/>
 * <p>
 * 注:由于引入多数据源,所以让spring事务的aop要在多数据源切换aop的后面
 *
 * @author stylefeng
 * @Date 2017/5/20 21:58
 */
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "true")
@EnableTransactionManagement(order = 2)
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao","com.stylefeng.guns.multi.mapper"})
public class MultiDataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "guns.muti-datasource")
    public MutiDataSourceProperties mutiDataSourceProperties() {
        return new MutiDataSourceProperties();
    }
    @Bean
    public MultiSourceExAop multiSourceExAop() {
        return new MultiSourceExAop();
    }
    /**
     * guns的数据源
     */
    private DruidDataSource dataSource(DruidProperties druidProperties) {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        return dataSource;
    }
    /**
     * 多数据源,第二个数据源
     */
    private DruidDataSource bizDataSource(DruidProperties druidProperties, MutiDataSourceProperties mutiDataSourceProperties) {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        mutiDataSourceProperties.config(dataSource);
        return dataSource;
    }
    /**
     * 多数据源连接池配置
     */
    @Bean
    public DynamicDataSource mutiDataSource(DruidProperties druidProperties, MutiDataSourceProperties mutiDataSourceProperties) {
        DruidDataSource dataSourceGuns = dataSource(druidProperties);
        DruidDataSource bizDataSource = bizDataSource(druidProperties, mutiDataSourceProperties);
        try {
            dataSourceGuns.init();
            bizDataSource.init();
        } catch (SQLException sql) {
            sql.printStackTrace();
        }
        DynamicDataSource dynamicDataSource = new DynamicDataSource();
        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put(mutiDataSourceProperties.getDataSourceNames()[0], dataSourceGuns);
        hashMap.put(mutiDataSourceProperties.getDataSourceNames()[1], bizDataSource);
        dynamicDataSource.setTargetDataSources(hashMap);
        dynamicDataSource.setDefaultTargetDataSource(dataSourceGuns);
        return dynamicDataSource;
    }
    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    /**
     * 数据范围mybatis插件
     */
    @Bean
    public DataScopeInterceptor dataScopeInterceptor() {
        return new DataScopeInterceptor();
    }
    /**
     * 乐观锁mybatis插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    /**
     * 事务配置
     *
     * @author stylefeng
     * @Date 2018/6/27 23:11
     */
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DynamicDataSource mutiDataSource) {
        return new DataSourceTransactionManager(mutiDataSource);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/datasource/SingleDataSourceConfig.java
New file
@@ -0,0 +1,61 @@
package com.stylefeng.guns.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.stylefeng.guns.core.config.properties.DruidProperties;
import com.stylefeng.guns.core.datascope.DataScopeInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
/**
 * 多数据源配置
 *
 * @author stylefeng
 * @Date 2017/5/20 21:58
 */
@Configuration
@ConditionalOnProperty(prefix = "guns.muti-datasource", name = "open", havingValue = "false", matchIfMissing = true)
@EnableTransactionManagement
@MapperScan(basePackages = {"com.stylefeng.guns.modular.*.dao"})
public class SingleDataSourceConfig {
    /**
     * 单数据源连接池配置
     */
    @Bean
    public DruidDataSource dataSource(DruidProperties druidProperties) {
        DruidDataSource dataSource = new DruidDataSource();
        druidProperties.config(dataSource);
        return dataSource;
    }
    /**
     * mybatis-plus分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    /**
     * 数据范围mybatis插件
     */
    @Bean
    public DataScopeInterceptor dataScopeInterceptor() {
        return new DataScopeInterceptor();
    }
    /**
     * 乐观锁mybatis插件
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/properties/BeetlProperties.java
New file
@@ -0,0 +1,103 @@
package com.stylefeng.guns.config.properties;
import com.stylefeng.guns.core.util.ToolUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
 * beetl配置(如果需要配置别的配置可参照这个形式自己添加)
 *
 * @author fengshuonan
 * @date 2017-05-24 20:37
 */
@Configuration
@ConfigurationProperties(prefix = BeetlProperties.BEETLCONF_PREFIX)
public class BeetlProperties {
    public static final String BEETLCONF_PREFIX = "beetl";
    private String delimiterStatementStart;
    private String delimiterStatementEnd;
    private String resourceTagroot;
    private String resourceTagsuffix;
    private String resourceAutoCheck;
    @Value("${spring.mvc.view.prefix}")
    private String prefix;
    public Properties getProperties(){
        Properties properties = new Properties();
        if(ToolUtil.isNotEmpty(delimiterStatementStart)){
            if(delimiterStatementStart.startsWith("\\")){
                delimiterStatementStart = delimiterStatementStart.substring(1);
            }
            properties.setProperty("DELIMITER_STATEMENT_START",delimiterStatementStart);
        }
        if(ToolUtil.isNotEmpty(delimiterStatementEnd)){
            properties.setProperty("DELIMITER_STATEMENT_END",delimiterStatementEnd);
        }else{
            properties.setProperty("DELIMITER_STATEMENT_END","null");
        }
        if(ToolUtil.isNotEmpty(resourceTagroot)){
            properties.setProperty("RESOURCE.tagRoot",resourceTagroot);
        }
        if(ToolUtil.isNotEmpty(resourceTagsuffix)){
            properties.setProperty("RESOURCE.tagSuffix",resourceTagsuffix);
        }
        if(ToolUtil.isNotEmpty(resourceAutoCheck)){
            properties.setProperty("RESOURCE.autoCheck",resourceAutoCheck);
        }
        return properties;
    }
    public String getPrefix() {
        return prefix;
    }
    public String getDelimiterStatementStart() {
        return delimiterStatementStart;
    }
    public void setDelimiterStatementStart(String delimiterStatementStart) {
        this.delimiterStatementStart = delimiterStatementStart;
    }
    public String getDelimiterStatementEnd() {
        return delimiterStatementEnd;
    }
    public void setDelimiterStatementEnd(String delimiterStatementEnd) {
        this.delimiterStatementEnd = delimiterStatementEnd;
    }
    public String getResourceTagroot() {
        return resourceTagroot;
    }
    public void setResourceTagroot(String resourceTagroot) {
        this.resourceTagroot = resourceTagroot;
    }
    public String getResourceTagsuffix() {
        return resourceTagsuffix;
    }
    public void setResourceTagsuffix(String resourceTagsuffix) {
        this.resourceTagsuffix = resourceTagsuffix;
    }
    public String getResourceAutoCheck() {
        return resourceAutoCheck;
    }
    public void setResourceAutoCheck(String resourceAutoCheck) {
        this.resourceAutoCheck = resourceAutoCheck;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/properties/GunsProperties.java
New file
@@ -0,0 +1,105 @@
package com.stylefeng.guns.config.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.File;
import static com.stylefeng.guns.core.util.ToolUtil.getTempPath;
import static com.stylefeng.guns.core.util.ToolUtil.isEmpty;
/**
 * guns项目配置
 *
 * @author stylefeng
 * @Date 2017/5/23 22:31
 */
@Component
@ConfigurationProperties(prefix = GunsProperties.PREFIX)
public class GunsProperties {
    public static final String PREFIX = "guns";
    private Boolean kaptchaOpen = false;
    private Boolean swaggerOpen = false;
    private String fileUploadPath;
    private Boolean haveCreatePath = false;
    private Boolean springSessionOpen = false;
    /**
     * session 失效时间(默认为30分钟 单位:秒)
     */
    private Integer sessionInvalidateTime = 30 * 60;
    /**
     * session 验证失效时间(默认为15分钟 单位:秒)
     */
    private Integer sessionValidationInterval = 15 * 60;
    public String getFileUploadPath() {
        //如果没有写文件上传路径,保存到临时目录
        if (isEmpty(fileUploadPath)) {
            return getTempPath();
        } else {
            //判断有没有结尾符,没有得加上
            if (!fileUploadPath.endsWith(File.separator)) {
                fileUploadPath = fileUploadPath + File.separator;
            }
            //判断目录存不存在,不存在得加上
            if (!haveCreatePath) {
                File file = new File(fileUploadPath);
                file.mkdirs();
                haveCreatePath = true;
            }
            return fileUploadPath;
        }
    }
    public void setFileUploadPath(String fileUploadPath) {
        this.fileUploadPath = fileUploadPath;
    }
    public Boolean getKaptchaOpen() {
        return kaptchaOpen;
    }
    public void setKaptchaOpen(Boolean kaptchaOpen) {
        this.kaptchaOpen = kaptchaOpen;
    }
    public Boolean getSwaggerOpen() {
        return swaggerOpen;
    }
    public void setSwaggerOpen(Boolean swaggerOpen) {
        this.swaggerOpen = swaggerOpen;
    }
    public Boolean getSpringSessionOpen() {
        return springSessionOpen;
    }
    public void setSpringSessionOpen(Boolean springSessionOpen) {
        this.springSessionOpen = springSessionOpen;
    }
    public Integer getSessionInvalidateTime() {
        return sessionInvalidateTime;
    }
    public void setSessionInvalidateTime(Integer sessionInvalidateTime) {
        this.sessionInvalidateTime = sessionInvalidateTime;
    }
    public Integer getSessionValidationInterval() {
        return sessionValidationInterval;
    }
    public void setSessionValidationInterval(Integer sessionValidationInterval) {
        this.sessionValidationInterval = sessionValidationInterval;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/web/BeetlConfig.java
New file
@@ -0,0 +1,46 @@
package com.stylefeng.guns.config.web;
import com.stylefeng.guns.config.properties.BeetlProperties;
import com.stylefeng.guns.core.beetl.BeetlConfiguration;
import org.beetl.core.resource.ClasspathResourceLoader;
import org.beetl.ext.spring.BeetlSpringViewResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
 * web 配置类
 *
 * @author fengshuonan
 * @date 2016年11月12日 下午5:03:32
 */
@Configuration
public class BeetlConfig {
    @Autowired
    BeetlProperties beetlProperties;
    /**
     * beetl的配置
     */
    @Bean(initMethod = "init")
    public BeetlConfiguration beetlConfiguration() {
        BeetlConfiguration beetlConfiguration = new BeetlConfiguration();
        beetlConfiguration.setResourceLoader(new ClasspathResourceLoader(BeetlConfig.class.getClassLoader(), beetlProperties.getPrefix()));
        beetlConfiguration.setConfigProperties(beetlProperties.getProperties());
        return beetlConfiguration;
    }
    /**
     * beetl的视图解析器
     */
    @Bean
    public BeetlSpringViewResolver beetlViewResolver() {
        BeetlSpringViewResolver beetlSpringViewResolver = new BeetlSpringViewResolver();
        beetlSpringViewResolver.setConfig(beetlConfiguration());
        beetlSpringViewResolver.setContentType("text/html;charset=UTF-8");
        beetlSpringViewResolver.setOrder(0);
        return beetlSpringViewResolver;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/web/ShiroConfig.java
New file
@@ -0,0 +1,219 @@
package com.stylefeng.guns.config.web;
import com.stylefeng.guns.config.properties.GunsProperties;
import com.stylefeng.guns.core.intercept.GunsUserFilter;
import com.stylefeng.guns.core.shiro.ShiroDbRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.ehcache.EhCacheManager;
import org.apache.shiro.codec.Base64;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.spring.LifecycleBeanPostProcessor;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.CookieRememberMeManager;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.servlet.Cookie;
import org.apache.shiro.web.servlet.ShiroHttpSession;
import org.apache.shiro.web.servlet.SimpleCookie;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.ServletContainerSessionManager;
import org.springframework.beans.factory.config.MethodInvokingFactoryBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.ehcache.EhCacheManagerFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
/**
 * shiro权限管理的配置
 *
 * @author fengshuonan
 * @date 2016年11月14日 下午3:03:44
 */
@Configuration
public class ShiroConfig {
    /**
     * 安全管理器
     */
    @Bean
    public DefaultWebSecurityManager securityManager(CookieRememberMeManager rememberMeManager, CacheManager cacheShiroManager, SessionManager sessionManager) {
        DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
        securityManager.setRealm(this.shiroDbRealm());
        securityManager.setCacheManager(cacheShiroManager);
        securityManager.setRememberMeManager(rememberMeManager);
        securityManager.setSessionManager(sessionManager);
        return securityManager;
    }
    /**
     * spring session管理器(多机环境)
     */
    @Bean
    @ConditionalOnProperty(prefix = "guns", name = "spring-session-open", havingValue = "true")
    public ServletContainerSessionManager servletContainerSessionManager() {
        return new ServletContainerSessionManager();
    }
    /**
     * session管理器(单机环境)
     */
    @Bean
    @ConditionalOnProperty(prefix = "guns", name = "spring-session-open", havingValue = "false")
    public DefaultWebSessionManager defaultWebSessionManager(CacheManager cacheShiroManager, GunsProperties gunsProperties) {
        DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
        sessionManager.setCacheManager(cacheShiroManager);
        sessionManager.setSessionValidationInterval(gunsProperties.getSessionValidationInterval() * 1000);
        sessionManager.setGlobalSessionTimeout(gunsProperties.getSessionInvalidateTime() * 1000);
        sessionManager.setDeleteInvalidSessions(true);
        sessionManager.setSessionValidationSchedulerEnabled(true);
        Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
        cookie.setName("shiroCookie");
        cookie.setHttpOnly(true);
        sessionManager.setSessionIdCookie(cookie);
        return sessionManager;
    }
    /**
     * 缓存管理器 使用Ehcache实现
     */
    @Bean
    public CacheManager getCacheShiroManager(EhCacheManagerFactoryBean ehcache) {
        EhCacheManager ehCacheManager = new EhCacheManager();
        ehCacheManager.setCacheManager(ehcache.getObject());
        return ehCacheManager;
    }
    /**
     * 项目自定义的Realm
     */
    @Bean
    public ShiroDbRealm shiroDbRealm() {
        return new ShiroDbRealm();
    }
    /**
     * rememberMe管理器, cipherKey生成见{@code Base64Test.java}
     */
    @Bean
    public CookieRememberMeManager rememberMeManager(SimpleCookie rememberMeCookie) {
        CookieRememberMeManager manager = new CookieRememberMeManager();
//        manager.setCipherKey(Base64.decode("Z3VucwAAAAAAAAAAAAAAAA=="));//取消硬编码密钥,防止Shiro反序列化漏洞
        manager.setCookie(rememberMeCookie);
        return manager;
    }
    /**
     * 记住密码Cookie
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
//        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");//取消记住我的cookie关键字,避免被扫描
        SimpleCookie simpleCookie = new SimpleCookie("");
        simpleCookie.setHttpOnly(true);
        simpleCookie.setMaxAge(7 * 24 * 60 * 60);//7天
        return simpleCookie;
    }
    /**
     * Shiro的过滤器链
     */
    @Bean
    public ShiroFilterFactoryBean shiroFilter(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
        shiroFilter.setSecurityManager(securityManager);
        /**
         * 默认的登录访问url
         */
        shiroFilter.setLoginUrl("/login");
        /**
         * 登录成功后跳转的url
         */
        shiroFilter.setSuccessUrl("/");
        /**
         * 没有权限跳转的url
         */
        shiroFilter.setUnauthorizedUrl("/global/error");
        /**
         * 覆盖默认的user拦截器(默认拦截器解决不了ajax请求 session超时的问题,若有更好的办法请及时反馈作者)
         */
        HashMap<String, Filter> myFilters = new HashMap<>();
        myFilters.put("user", new GunsUserFilter());
        shiroFilter.setFilters(myFilters);
        /**
         * 配置shiro拦截器链
         *
         * anon  不需要认证
         * authc 需要认证
         * user  验证通过或RememberMe登录的都可以
         *
         * 当应用开启了rememberMe时,用户下次访问时可以是一个user,但不会是authc,因为authc是需要重新认证的
         *
         * 顺序从上到下,优先级依次降低
         *
         * api开头的接口,走rest api鉴权,不走shiro鉴权
         *
         */
        Map<String, String> hashMap = new LinkedHashMap<>();
        hashMap.put("/swagger-ui.html", "anon");
        hashMap.put("/swagger-resources/**", "anon");
        hashMap.put("/v2/**", "anon");
        hashMap.put("/webjars/**", "anon");
        hashMap.put("/swagger-resources/configuration/ui/**", "anon");
        hashMap.put("/swagger-resources/configuration/security/**", "anon");
        hashMap.put("/base/**", "anon");
        hashMap.put("/upload/**", "anon");
        hashMap.put("/api/**", "anon");
        hashMap.put("/auth/**", "anon");
        hashMap.put("/static/**", "anon");
        hashMap.put("/gunsApi/**", "anon");
        hashMap.put("/login", "anon");
        hashMap.put("/updatepwdpage", "anon");
        hashMap.put("/updatepwd", "anon");
        hashMap.put("/global/sessionError", "anon");
        hashMap.put("/kaptcha", "anon");
        hashMap.put("/**", "user");
        shiroFilter.setFilterChainDefinitionMap(hashMap);
        return shiroFilter;
    }
    /**
     * 在方法中 注入 securityManager,进行代理控制
     */
    @Bean
    public MethodInvokingFactoryBean methodInvokingFactoryBean(DefaultWebSecurityManager securityManager) {
        MethodInvokingFactoryBean bean = new MethodInvokingFactoryBean();
        bean.setStaticMethod("org.apache.shiro.SecurityUtils.setSecurityManager");
        bean.setArguments(new Object[]{securityManager});
        return bean;
    }
    /**
     * Shiro生命周期处理器:
     * 用于在实现了Initializable接口的Shiro bean初始化时调用Initializable接口回调(例如:UserRealm)
     * 在实现了Destroyable接口的Shiro bean销毁时调用 Destroyable接口回调(例如:DefaultSecurityManager)
     */
    @Bean
    public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
        return new LifecycleBeanPostProcessor();
    }
    /**
     * 启用shrio授权注解拦截方式,AOP式方法级权限检查
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
                new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/config/web/WebConfig.java
New file
@@ -0,0 +1,176 @@
package com.stylefeng.guns.config.web;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.stylefeng.guns.config.properties.GunsProperties;
import com.stylefeng.guns.core.intercept.RestApiInteceptor;
import com.stylefeng.guns.core.listener.ConfigListener;
import com.stylefeng.guns.core.xss.XssFilter;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import java.util.Arrays;
import java.util.Properties;
/**
 * web 配置类
 *
 * @author fengshuonan
 * @date 2016年11月12日 下午5:03:32
 */
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
    @Autowired
    private GunsProperties gunsProperties;
    /**
     * 增加swagger的支持
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        if (gunsProperties.getSwaggerOpen()) {
            registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
            registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
        }
    }
    /**
     * 增加对rest api鉴权的spring mvc拦截器
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new RestApiInteceptor())
                .addPathPatterns("/api/**", "/auth/**")
                .excludePathPatterns("/upload/**");
    }
    /**
     * druidServlet注册
     */
    @Bean
    public ServletRegistrationBean druidServletRegistration() {
        ServletRegistrationBean registration = new ServletRegistrationBean(new StatViewServlet());
        registration.addUrlMappings("/druid/*");
        return registration;
    }
    /**
     * druid监控 配置URI拦截策略
     */
    @Bean
    public FilterRegistrationBean druidStatFilter() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter());
        //添加过滤规则.
        filterRegistrationBean.addUrlPatterns("/*");
        //添加不需要忽略的格式信息.
        filterRegistrationBean.addInitParameter(
                "exclusions", "/static/*,*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid,/druid/*");
        //用于session监控页面的用户名显示 需要登录后主动将username注入到session里
        filterRegistrationBean.addInitParameter("principalSessionName", "username");
        return filterRegistrationBean;
    }
    /**
     * druid数据库连接池监控
     */
    @Bean
    public DruidStatInterceptor druidStatInterceptor() {
        return new DruidStatInterceptor();
    }
    @Bean
    public JdkRegexpMethodPointcut druidStatPointcut() {
        JdkRegexpMethodPointcut druidStatPointcut = new JdkRegexpMethodPointcut();
        String patterns = "com.stylefeng.guns.modular.*.service.*";
        //可以set多个
        druidStatPointcut.setPatterns(patterns);
        return druidStatPointcut;
    }
    /**
     * druid数据库连接池监控
     */
    @Bean
    public BeanTypeAutoProxyCreator beanTypeAutoProxyCreator() {
        BeanTypeAutoProxyCreator beanTypeAutoProxyCreator = new BeanTypeAutoProxyCreator();
        beanTypeAutoProxyCreator.setTargetBeanType(DruidDataSource.class);
        beanTypeAutoProxyCreator.setInterceptorNames("druidStatInterceptor");
        return beanTypeAutoProxyCreator;
    }
    /**
     * druid 为druidStatPointcut添加拦截
     *
     * @return
     */
    @Bean
    public Advisor druidStatAdvisor() {
        return new DefaultPointcutAdvisor(druidStatPointcut(), druidStatInterceptor());
    }
    /**
     * xssFilter注册
     */
    @Bean
    public FilterRegistrationBean xssFilterRegistration() {
        XssFilter xssFilter = new XssFilter();
        xssFilter.setUrlExclusion(Arrays.asList("/notice/update", "/notice/add"));
        FilterRegistrationBean registration = new FilterRegistrationBean(xssFilter);
        registration.addUrlPatterns("/*");
        return registration;
    }
    /**
     * RequestContextListener注册
     */
    @Bean
    public ServletListenerRegistrationBean<RequestContextListener> requestContextListenerRegistration() {
        return new ServletListenerRegistrationBean<>(new RequestContextListener());
    }
    /**
     * ConfigListener注册
     */
    @Bean
    public ServletListenerRegistrationBean<ConfigListener> configListenerRegistration() {
        return new ServletListenerRegistrationBean<>(new ConfigListener());
    }
    /**
     * 验证码生成相关
     */
    @Bean
    public DefaultKaptcha kaptcha() {
        Properties properties = new Properties();
        properties.put("kaptcha.border", "no");
        properties.put("kaptcha.border.color", "105,179,90");
        properties.put("kaptcha.textproducer.font.color", "blue");
        properties.put("kaptcha.image.width", "125");
        properties.put("kaptcha.image.height", "45");
        properties.put("kaptcha.textproducer.font.size", "45");
        properties.put("kaptcha.session.key", "code");
        properties.put("kaptcha.textproducer.char.length", "4");
        properties.put("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/aop/GlobalExceptionHandler.java
New file
@@ -0,0 +1,123 @@
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.common.exception.InvalidKaptchaException;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogManager;
import com.stylefeng.guns.core.log.factory.LogTaskFactory;
import com.stylefeng.guns.core.shiro.ShiroKit;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.DisabledAccountException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.ui.Model;
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.ResponseStatus;
import java.lang.reflect.UndeclaredThrowableException;
import static com.stylefeng.guns.core.support.HttpKit.getIp;
import static com.stylefeng.guns.core.support.HttpKit.getRequest;
/**
 * 全局的的异常拦截器(拦截所有的控制器)(带有@RequestMapping注解的方法上都会拦截)
 *
 * @author fengshuonan
 * @date 2016年11月12日 下午3:19:56
 */
@ControllerAdvice
@Order(-1)
public class GlobalExceptionHandler {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    /**
     * 拦截业务异常
     */
    @ExceptionHandler(GunsException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ErrorTip notFount(GunsException e) {
        LogManager.me().executeLog(LogTaskFactory.exceptionLog(ShiroKit.getUser().getId(), e));
        getRequest().setAttribute("tip", e.getMessage());
        log.error("业务异常:", e);
        return new ErrorTip(e.getCode(), e.getMessage());
    }
    /**
     * 用户未登录异常
     */
    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public String unAuth(AuthenticationException e) {
        log.error("用户未登录:", e);
        return "/login.html";
    }
    /**
     * 账号被冻结异常
     */
    @ExceptionHandler(DisabledAccountException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public String accountLocked(DisabledAccountException e, Model model) {
        String username = getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "账号被冻结", getIp()));
        model.addAttribute("tips", "账号被冻结");
        return "/login.html";
    }
    /**
     * 账号密码错误异常
     */
    @ExceptionHandler(CredentialsException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public String credentials(CredentialsException e, Model model) {
        String username = getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "账号密码错误", getIp()));
        model.addAttribute("tips", "账号密码错误");
        return "/login.html";
    }
    /**
     * 验证码错误异常
     */
    @ExceptionHandler(InvalidKaptchaException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String credentials(InvalidKaptchaException e, Model model) {
        String username = getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "验证码错误", getIp()));
        model.addAttribute("tips", "验证码错误");
        return "/login.html";
    }
    /**
     * 无权访问该资源异常
     */
    @ExceptionHandler(UndeclaredThrowableException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public ErrorTip credentials(UndeclaredThrowableException e) {
        getRequest().setAttribute("tip", "权限异常");
        log.error("权限异常!", e);
        return new ErrorTip(BizExceptionEnum.NO_PERMITION.getCode(), BizExceptionEnum.NO_PERMITION.getMessage());
    }
    /**
     * 拦截未知的运行时异常
     */
    @ExceptionHandler(RuntimeException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public ErrorTip notFount(RuntimeException e) {
        LogManager.me().executeLog(LogTaskFactory.exceptionLog(ShiroKit.getUser().getId(), e));
        getRequest().setAttribute("tip", "服务器未知运行时异常");
        log.error("运行时异常:", e);
        return new ErrorTip(BizExceptionEnum.SERVER_ERROR.getCode(), BizExceptionEnum.SERVER_ERROR.getMessage());
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/aop/LogAop.java
New file
@@ -0,0 +1,105 @@
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
import com.stylefeng.guns.core.log.LogManager;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.log.factory.LogTaskFactory;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.Contrast;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Map;
/**
 * 日志记录
 *
 * @author fengshuonan
 * @date 2016年12月6日 下午8:48:30
 */
@Aspect
@Component
public class LogAop {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Pointcut(value = "@annotation(com.stylefeng.guns.core.common.annotion.BussinessLog)")
    public void cutService() {
    }
    @Around("cutService()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
        //先执行业务
        Object result = point.proceed();
        try {
            handle(point);
        } catch (Exception e) {
            log.error("日志记录出错!", e);
        }
        return result;
    }
    private void handle(ProceedingJoinPoint point) throws Exception {
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        //如果当前用户未登录,不做日志
        ShiroUser user = ShiroKit.getUser();
        if (null == user) {
            return;
        }
        //获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();
        //获取操作名称
        BussinessLog annotation = currentMethod.getAnnotation(BussinessLog.class);
        String bussinessName = annotation.value();
        String key = annotation.key();
        Class dictClass = annotation.dict();
        StringBuilder sb = new StringBuilder();
        for (Object param : params) {
            sb.append(param);
            sb.append(" & ");
        }
        //如果涉及到修改,比对变化
        String msg;
        if (bussinessName.indexOf("修改") != -1 || bussinessName.indexOf("编辑") != -1) {
            Object obj1 = LogObjectHolder.me().get();
            Map<String, String> obj2 = HttpKit.getRequestParameters();
            msg = Contrast.contrastObj(dictClass, key, obj1, obj2);
        } else {
            Map<String, String> parameters = HttpKit.getRequestParameters();
            AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
            msg = Contrast.parseMutiKey(dictMap,key,parameters);
        }
        LogManager.me().executeLog(LogTaskFactory.bussinessLog(user.getId(), bussinessName, className, methodName, msg));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/aop/PermissionAop.java
New file
@@ -0,0 +1,70 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.aop;
import com.stylefeng.guns.core.common.annotion.Permission;
import com.stylefeng.guns.core.shiro.check.PermissionCheckManager;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.naming.NoPermissionException;
import java.lang.reflect.Method;
/**
 * AOP 权限自定义检查
 */
@Aspect
@Component
@Order(200)
public class PermissionAop {
    @Pointcut(value = "@annotation(com.stylefeng.guns.core.common.annotion.Permission)")
    private void cutPermission() {
    }
    @Around("cutPermission()")
    public Object doPermission(ProceedingJoinPoint point) throws Throwable {
        MethodSignature ms = (MethodSignature) point.getSignature();
        Method method = ms.getMethod();
        Permission permission = method.getAnnotation(Permission.class);
        Object[] permissions = permission.value();
        if (permissions == null || permissions.length == 0) {
            //检查全体角色
            boolean result = PermissionCheckManager.checkAll();
            if (result) {
                return point.proceed();
            } else {
                throw new NoPermissionException();
            }
        } else {
            //检查指定角色
            boolean result = PermissionCheckManager.check(permissions);
            if (result) {
                return point.proceed();
            } else {
                throw new NoPermissionException();
            }
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/beetl/BeetlConfiguration.java
New file
@@ -0,0 +1,71 @@
package com.stylefeng.guns.core.beetl;
import com.stylefeng.guns.core.tag.DictSelectorTag;
import com.stylefeng.guns.core.util.KaptchaUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import org.beetl.core.Context;
import org.beetl.core.Function;
import org.beetl.core.Tag;
import org.beetl.core.TagFactory;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import java.io.UnsupportedEncodingException;
/**
 * beetl拓展配置,绑定一些工具类,方便在模板中直接调用
 *
 * @author stylefeng
 * @Date 2018/2/22 21:03
 */
public class BeetlConfiguration extends BeetlGroupUtilConfiguration {
    @Autowired
    Environment env;
    @Autowired
    ApplicationContext applicationContext;
    @Autowired
    DictSelectorTag dictSelectorTag;
    @Override
    public void initOther() {
        groupTemplate.registerFunctionPackage("shiro", new ShiroExt());
        groupTemplate.registerFunctionPackage("tool", new ToolUtil());
        groupTemplate.registerFunctionPackage("kaptcha", new KaptchaUtil());
        groupTemplate.registerTagFactory("dictSelector", new TagFactory() {
            @Override
            public Tag createTag() {
                return dictSelectorTag;
            }
        });
        groupTemplate.registerFunction("env", new Function() {
            @Override
            public String call(Object[] paras, Context ctx) {
                String key = (String)paras[0];
                String value =  env.getProperty(key);
                if(value!=null) {
                    return getStr(value);
                }
                if(paras.length==2) {
                    return (String)paras[1];
                }
                return null;
            }
            protected String getStr(String str) {
                try {
                    return new String(str.getBytes("iso8859-1"),"UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
        });
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/beetl/ShiroExt.java
New file
@@ -0,0 +1,186 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.beetl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.beetl.core.GroupTemplate;
import com.stylefeng.guns.core.shiro.ShiroUser;
public class ShiroExt {
    private static final String NAMES_DELIMETER = ",";
    /**
     * 获取当前 Subject
     *
     * @return Subject
     */
    protected static Subject getSubject() {
        return SecurityUtils.getSubject();
    }
    /**
     * 获取封装的 ShiroUser
     *
     * @return ShiroUser
     */
    public ShiroUser getUser() {
        if (isGuest()) {
            return null;
        } else {
            return (ShiroUser) getSubject().getPrincipals().getPrimaryPrincipal();
        }
    }
    /**
     * 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
     *
     * @param roleName 角色名
     * @return 属于该角色:true,否则false
     */
    public boolean hasRole(String roleName) {
        return getSubject() != null && roleName != null
                && roleName.length() > 0 && getSubject().hasRole(roleName);
    }
    /**
     * 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
     *
     * @param roleName 角色名
     * @return 不属于该角色:true,否则false
     */
    public boolean lacksRole(String roleName) {
        return !hasRole(roleName);
    }
    /**
     * 验证当前用户是否属于以下任意一个角色。
     *
     * @param roleNames 角色列表
     * @return 属于:true,否则false
     */
    public boolean hasAnyRoles(String roleNames) {
        boolean hasAnyRole = false;
        Subject subject = getSubject();
        if (subject != null && roleNames != null && roleNames.length() > 0) {
            for (String role : roleNames.split(NAMES_DELIMETER)) {
                if (subject.hasRole(role.trim())) {
                    hasAnyRole = true;
                    break;
                }
            }
        }
        return hasAnyRole;
    }
    /**
     * 验证当前用户是否属于以下所有角色。
     *
     * @param roleNames 角色列表
     * @return 属于:true,否则false
     */
    public boolean hasAllRoles(String roleNames) {
        boolean hasAllRole = true;
        Subject subject = getSubject();
        if (subject != null && roleNames != null && roleNames.length() > 0) {
            for (String role : roleNames.split(NAMES_DELIMETER)) {
                if (!subject.hasRole(role.trim())) {
                    hasAllRole = false;
                    break;
                }
            }
        }
        return hasAllRole;
    }
    /**
     * 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
     *
     * @param permission 权限名
     * @return 拥有权限:true,否则false
     */
    public boolean hasPermission(String permission) {
        return getSubject() != null && permission != null
                && permission.length() > 0
                && getSubject().isPermitted(permission);
    }
    /**
     * 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
     *
     * @param permission 权限名
     * @return 拥有权限:true,否则false
     */
    public boolean lacksPermission(String permission) {
        return !hasPermission(permission);
    }
    /**
     * 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
     *
     * @return 通过身份验证:true,否则false
     */
    public boolean authenticated() {
        return getSubject() != null && getSubject().isAuthenticated();
    }
    /**
     * 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
     *
     * @return 没有通过身份验证:true,否则false
     */
    public boolean notAuthenticated() {
        return !authenticated();
    }
    /**
     * 认证通过或已记住的用户。与guset搭配使用。
     *
     * @return 用户:true,否则 false
     */
    public boolean isUser() {
        return getSubject() != null && getSubject().getPrincipal() != null;
    }
    /**
     * 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
     *
     * @return 访客:true,否则false
     */
    public boolean isGuest() {
        return !isUser();
    }
    /**
     * 输出当前用户信息,通常为登录帐号信息。
     *
     * @return 当前用户信息
     */
    public String principal() {
        if (getSubject() != null) {
            Object principal = getSubject().getPrincipal();
            return principal.toString();
        }
        return "";
    }
    public static void main(String[] args) {
        GroupTemplate gt = new GroupTemplate();
        gt.registerFunctionPackage("shiro", new ShiroExt());
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/annotion/BussinessLog.java
New file
@@ -0,0 +1,33 @@
package com.stylefeng.guns.core.common.annotion;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
import com.stylefeng.guns.core.common.constant.dictmap.base.SystemDict;
import java.lang.annotation.*;
/**
 * 标记需要做业务日志的方法
 *
 * @author fengshuonan
 * @date 2017-03-31 12:46
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface BussinessLog {
    /**
     * 业务的名称,例如:"修改菜单"
     */
    String value() default "";
    /**
     * 被修改的实体的唯一标识,例如:菜单实体的唯一标识为"id"
     */
    String key() default "id";
    /**
     * 字典(用于查找key的中文名称和字段的中文名称)
     */
    Class<? extends AbstractDictMap> dict() default SystemDict.class;
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/annotion/Permission.java
New file
@@ -0,0 +1,22 @@
package com.stylefeng.guns.core.common.annotion;
import java.lang.annotation.*;
/**
 * 权限注解 用于检查权限 规定访问权限
 *
 * @example @Permission({role1,role2})
 * @example @Permission
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Permission {
    /**
     * <p>角色英文名称</p>
     * <p>使用注解时加上这个值表示限制只有某个角色的才可以访问对应的资源</p>
     * <p>常用在某些资源限制只有超级管理员角色才可访问</p>
     */
    String[] value() default {};
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/Const.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.core.common.constant;
/**
 * 系统常量
 *
 * @author fengshuonan
 * @date 2017年2月12日 下午9:42:53
 */
public interface Const {
    /**
     * 系统默认的管理员密码
     */
    String DEFAULT_PWD = "111111";
    /**
     * 管理员角色的名字
     */
    String ADMIN_NAME = "administrator";
    /**
     * 管理员id
     */
    Integer ADMIN_ID = 1;
    /**
     * 超级管理员角色id
     */
    Integer ADMIN_ROLE_ID = 1;
    /**
     * 接口文档的菜单名
     */
    String API_MENU_NAME = "接口文档";
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/DatasourceEnum.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.core.common.constant;
/**
 *
 * 多数据源的枚举
 *
 * @author fengshuonan
 * @date 2017年3月5日 上午10:15:02
 */
public interface DatasourceEnum {
    String DATA_SOURCE_GUNS = "dataSourceGuns";            //guns数据源
    String DATA_SOURCE_BIZ = "dataSourceBiz";            //其他业务的数据源
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/JwtConstants.java
New file
@@ -0,0 +1,19 @@
package com.stylefeng.guns.core.common.constant;
/**
 * jwt相关配置
 *
 * @author fengshuonan
 * @date 2017-08-23 9:23
 */
public interface JwtConstants {
    String AUTH_HEADER = "Authorization";
    String SECRET = "defaultSecret";
    Long EXPIRATION = 604800L;
    String AUTH_PATH = "/gunsApi/auth";
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/cache/Cache.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.core.common.constant.cache;
/**
 * 所有缓存名称的集合
 *
 * @author fengshuonan
 * @date 2017-04-24 21:56
 */
public interface Cache {
    /**
     * 常量缓存
     */
    String CONSTANT = "CONSTANT";
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/cache/CacheKey.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.core.common.constant.cache;
/**
 * 缓存标识前缀集合,常用在ConstantFactory类中
 *
 * @author fengshuonan
 * @date 2017-04-25 9:37
 */
public interface CacheKey {
    /**
     * 角色名称(多个)
     */
    String ROLES_NAME = "roles_name_";
    /**
     * 角色名称(单个)
     */
    String SINGLE_ROLE_NAME = "single_role_name_";
    /**
     * 角色英文名称
     */
    String SINGLE_ROLE_TIP = "single_role_tip_";
    /**
     * 部门名称
     */
    String DEPT_NAME = "dept_name_";
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DeleteDict.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 用于删除业务的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class DeleteDict extends AbstractDictMap {
    @Override
    public void init() {
        put("roleId","角色名称");
        put("deptId", "部门名称");
        put("menuId", "菜单名称");
        put("dictId", "字典名称");
        put("noticeId", "标题");
    }
    @Override
    protected void initBeWrapped() {
        putFieldWrapperMethodName("roleId","getCacheObject");
        putFieldWrapperMethodName("deptId","getCacheObject");
        putFieldWrapperMethodName("menuId","getCacheObject");
        putFieldWrapperMethodName("dictId","getCacheObject");
        putFieldWrapperMethodName("noticeId","getCacheObject");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DeptDict.java
New file
@@ -0,0 +1,28 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 部门的映射
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class DeptDict extends AbstractDictMap {
    @Override
    public void init() {
        put("deptId", "部门名称");
        put("num", "部门排序");
        put("pid", "上级名称");
        put("simplename", "部门简称");
        put("fullname", "部门全称");
        put("tips", "备注");
    }
    @Override
    protected void initBeWrapped() {
        putFieldWrapperMethodName("deptId", "getDeptName");
        putFieldWrapperMethodName("pid", "getDeptName");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/DictMap.java
New file
@@ -0,0 +1,24 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 字典map
 *
 * @author fengshuonan
 * @date 2017-05-06 15:43
 */
public class DictMap extends AbstractDictMap {
    @Override
    public void init() {
        put("dictId","字典名称");
        put("dictName","字典名称");
        put("dictValues","字典内容");
    }
    @Override
    protected void initBeWrapped() {
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/LogDict.java
New file
@@ -0,0 +1,22 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 日志的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class LogDict extends AbstractDictMap {
    @Override
    public void init() {
        put("tips","备注");
    }
    @Override
    protected void initBeWrapped() {
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/MenuDict.java
New file
@@ -0,0 +1,34 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 菜单的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class MenuDict extends AbstractDictMap {
    @Override
    public void init() {
        put("menuId","菜单id");
        put("id","菜单id");
        put("code","菜单编号");
        put("pcode","菜单父编号");
        put("name","菜单名称");
        put("icon","菜单图标");
        put("url","url地址");
        put("num","菜单排序号");
        put("levels","菜单层级");
        put("tips","备注");
        put("status","菜单状态");
        put("isopen","是否打开");
        put("","");
    }
    @Override
    protected void initBeWrapped() {
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/NoticeMap.java
New file
@@ -0,0 +1,22 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 通知的映射
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class NoticeMap extends AbstractDictMap {
    @Override
    public void init() {
        put("title", "标题");
        put("content", "内容");
    }
    @Override
    protected void initBeWrapped() {
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/RoleDict.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 角色的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class RoleDict extends AbstractDictMap {
    @Override
    public void init() {
        put("roleId","角色名称");
        put("num","角色排序");
        put("pid","角色的父级");
        put("name","角色名称");
        put("deptid","部门名称");
        put("tips","备注");
        put("ids","资源名称");
    }
    @Override
    protected void initBeWrapped() {
        putFieldWrapperMethodName("pid","getSingleRoleName");
        putFieldWrapperMethodName("deptid","getDeptName");
        putFieldWrapperMethodName("roleId","getSingleRoleName");
        putFieldWrapperMethodName("ids","getMenuNames");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/UserDict.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.core.common.constant.dictmap;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
/**
 * 用户的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:01
 */
public class UserDict extends AbstractDictMap {
    @Override
    public void init() {
        put("userId","账号");
        put("avatar","头像");
        put("account","账号");
        put("name","名字");
        put("birthday","生日");
        put("sex","性别");
        put("email","电子邮件");
        put("phone","电话");
        put("roleid","角色名称");
        put("deptid","部门名称");
        put("roleIds","角色名称集合");
    }
    @Override
    protected void initBeWrapped() {
        putFieldWrapperMethodName("sex","getSexName");
        putFieldWrapperMethodName("deptid","getDeptName");
        putFieldWrapperMethodName("roleid","getSingleRoleName");
        putFieldWrapperMethodName("userId","getUserAccountById");
        putFieldWrapperMethodName("roleIds","getRoleName");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/base/AbstractDictMap.java
New file
@@ -0,0 +1,53 @@
package com.stylefeng.guns.core.common.constant.dictmap.base;
import java.util.HashMap;
/**
 * 字典映射抽象类
 *
 * @author fengshuonan
 * @date 2017-05-06 14:58
 */
public abstract class AbstractDictMap {
    protected HashMap<String, String> dictory = new HashMap<>();
    protected HashMap<String, String> fieldWarpperDictory = new HashMap<>();
    public AbstractDictMap(){
        put("id","主键id");
        init();
        initBeWrapped();
    }
    /**
     * 初始化字段英文名称和中文名称对应的字典
     *
     * @author stylefeng
     * @Date 2017/5/9 19:39
     */
    public abstract void init();
    /**
     * 初始化需要被包装的字段(例如:性别为1:男,2:女,需要被包装为汉字)
     *
     * @author stylefeng
     * @Date 2017/5/9 19:35
     */
    protected abstract void initBeWrapped();
    public String get(String key) {
        return this.dictory.get(key);
    }
    public void put(String key, String value) {
        this.dictory.put(key, value);
    }
    public String getFieldWarpperMethodName(String key){
        return this.fieldWarpperDictory.get(key);
    }
    public void putFieldWrapperMethodName(String key,String methodName){
        this.fieldWarpperDictory.put(key,methodName);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/base/SystemDict.java
New file
@@ -0,0 +1,20 @@
package com.stylefeng.guns.core.common.constant.dictmap.base;
/**
 * 系统相关的字典
 *
 * @author fengshuonan
 * @date 2017-05-06 15:48
 */
public class SystemDict extends AbstractDictMap {
    @Override
    public void init() {
    }
    @Override
    protected void initBeWrapped() {
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/dictmap/factory/DictFieldWarpperFactory.java
New file
@@ -0,0 +1,33 @@
package com.stylefeng.guns.core.common.constant.dictmap.factory;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.constant.factory.IConstantFactory;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import java.lang.reflect.Method;
/**
 * 字典字段的包装器(从ConstantFactory中获取包装值)
 *
 * @author fengshuonan
 * @date 2017-05-06 15:12
 */
public class DictFieldWarpperFactory {
    public static Object createFieldWarpper(Object parameter, String methodName) {
        IConstantFactory constantFactory = ConstantFactory.me();
        try {
            Method method = IConstantFactory.class.getMethod(methodName, parameter.getClass());
            return method.invoke(constantFactory, parameter);
        } catch (Exception e) {
            try {
                Method method = IConstantFactory.class.getMethod(methodName, Integer.class);
                return method.invoke(constantFactory, Integer.parseInt(parameter.toString()));
            } catch (Exception e1) {
                throw new GunsException(BizExceptionEnum.ERROR_WRAPPER_FIELD);
            }
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/ConstantFactory.java
New file
@@ -0,0 +1,345 @@
package com.stylefeng.guns.core.common.constant.factory;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.stylefeng.guns.core.common.constant.cache.Cache;
import com.stylefeng.guns.core.common.constant.cache.CacheKey;
import com.stylefeng.guns.core.common.constant.state.ManagerStatus;
import com.stylefeng.guns.core.common.constant.state.MenuStatus;
import com.stylefeng.guns.modular.system.dao.*;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.support.StrKit;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.SpringContextHolder;
import com.stylefeng.guns.core.util.ToolUtil;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
/**
 * 常量的生产工厂
 *
 * @author fengshuonan
 * @date 2017年2月13日 下午10:55:21
 */
@Component
@DependsOn("springContextHolder")
public class ConstantFactory implements IConstantFactory {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private DeptMapper deptMapper;
    @Resource
    private DictMapper dictMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private NoticeMapper noticeMapper;
    public static IConstantFactory me() {
        return SpringContextHolder.getBean("constantFactory");
    }
    /**
     * 根据用户id获取用户名称
     *
     * @author stylefeng
     * @Date 2017/5/9 23:41
     */
    @Override
    public String getUserNameById(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            return user.getName();
        } else {
            return "--";
        }
    }
    /**
     * 根据用户id获取用户账号
     *
     * @author stylefeng
     * @date 2017年5月16日21:55:371
     */
    @Override
    public String getUserAccountById(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            return user.getAccount();
        } else {
            return "--";
        }
    }
    /**
     * 通过角色ids获取角色名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.ROLES_NAME + "'+#roleIds")
    public String getRoleName(String roleIds) {
        Integer[] roles = Convert.toIntArray(roleIds);
        StringBuilder sb = new StringBuilder();
        for (int role : roles) {
            Role roleObj = roleMapper.selectById(role);
            if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
                sb.append(roleObj.getName()).append(",");
            }
        }
        return StrKit.removeSuffix(sb.toString(), ",");
    }
    /**
     * 通过角色id获取角色名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_NAME + "'+#roleId")
    public String getSingleRoleName(Integer roleId) {
        if (0 == roleId) {
            return "--";
        }
        Role roleObj = roleMapper.selectById(roleId);
        if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
            return roleObj.getName();
        }
        return "";
    }
    /**
     * 通过角色id获取角色英文名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.SINGLE_ROLE_TIP + "'+#roleId")
    public String getSingleRoleTip(Integer roleId) {
        if (0 == roleId) {
            return "--";
        }
        Role roleObj = roleMapper.selectById(roleId);
        if (ToolUtil.isNotEmpty(roleObj) && ToolUtil.isNotEmpty(roleObj.getName())) {
            return roleObj.getTips();
        }
        return "";
    }
    /**
     * 获取部门名称
     */
    @Override
    @Cacheable(value = Cache.CONSTANT, key = "'" + CacheKey.DEPT_NAME + "'+#deptId")
    public String getDeptName(Integer deptId) {
        Dept dept = deptMapper.selectById(deptId);
        if (ToolUtil.isNotEmpty(dept) && ToolUtil.isNotEmpty(dept.getFullname())) {
            return dept.getFullname();
        }
        return "";
    }
    /**
     * 获取菜单的名称们(多个)
     */
    @Override
    public String getMenuNames(String menuIds) {
        Integer[] menus = Convert.toIntArray(menuIds);
        StringBuilder sb = new StringBuilder();
        for (int menu : menus) {
            Menu menuObj = menuMapper.selectById(menu);
            if (ToolUtil.isNotEmpty(menuObj) && ToolUtil.isNotEmpty(menuObj.getName())) {
                sb.append(menuObj.getName()).append(",");
            }
        }
        return StrKit.removeSuffix(sb.toString(), ",");
    }
    /**
     * 获取菜单名称
     */
    @Override
    public String getMenuName(Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            return "";
        } else {
            Menu menu = menuMapper.selectById(menuId);
            if (menu == null) {
                return "";
            } else {
                return menu.getName();
            }
        }
    }
    /**
     * 获取菜单名称通过编号
     */
    @Override
    public String getMenuNameByCode(String code) {
        if (ToolUtil.isEmpty(code)) {
            return "";
        } else {
            Menu param = new Menu();
            param.setCode(code);
            Menu menu = menuMapper.selectOne(param);
            if (menu == null) {
                return "";
            } else {
                return menu.getName();
            }
        }
    }
    /**
     * 获取字典名称
     */
    @Override
    public String getDictName(Integer dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Dict dict = dictMapper.selectById(dictId);
            if (dict == null) {
                return "";
            } else {
                return dict.getName();
            }
        }
    }
    /**
     * 获取通知标题
     */
    @Override
    public String getNoticeTitle(Integer dictId) {
        if (ToolUtil.isEmpty(dictId)) {
            return "";
        } else {
            Notice notice = noticeMapper.selectById(dictId);
            if (notice == null) {
                return "";
            } else {
                return notice.getTitle();
            }
        }
    }
    /**
     * 根据字典名称和字典中的值获取对应的名称
     */
    @Override
    public String getDictsByName(String name, Integer val) {
        Dict temp = new Dict();
        temp.setName(name);
        Dict dict = dictMapper.selectOne(temp);
        if (dict == null) {
            return "";
        } else {
            Wrapper<Dict> wrapper = new EntityWrapper<>();
            wrapper = wrapper.eq("pid", dict.getId());
            List<Dict> dicts = dictMapper.selectList(wrapper);
            for (Dict item : dicts) {
                if (item.getNum() != null && item.getNum().equals(val)) {
                    return item.getName();
                }
            }
            return "";
        }
    }
    /**
     * 获取性别名称
     */
    @Override
    public String getSexName(Integer sex) {
        return getDictsByName("性别", sex);
    }
    /**
     * 获取用户登录状态
     */
    @Override
    public String getStatusName(Integer status) {
        return ManagerStatus.valueOf(status);
    }
    /**
     * 获取菜单状态
     */
    @Override
    public String getMenuStatusName(Integer status) {
        return MenuStatus.valueOf(status);
    }
    /**
     * 查询字典
     */
    @Override
    public List<Dict> findInDict(Integer id) {
        if (ToolUtil.isEmpty(id)) {
            return null;
        } else {
            EntityWrapper<Dict> wrapper = new EntityWrapper<>();
            List<Dict> dicts = dictMapper.selectList(wrapper.eq("pid", id));
            if (dicts == null || dicts.size() == 0) {
                return null;
            } else {
                return dicts;
            }
        }
    }
    /**
     * 获取被缓存的对象(用户删除业务)
     */
    @Override
    public String getCacheObject(String para) {
        return LogObjectHolder.me().get().toString();
    }
    /**
     * 获取子部门id
     */
    @Override
    public List<Integer> getSubDeptId(Integer deptid) {
        Wrapper<Dept> wrapper = new EntityWrapper<>();
        wrapper = wrapper.like("pids", "%[" + deptid + "]%");
        List<Dept> depts = this.deptMapper.selectList(wrapper);
        ArrayList<Integer> deptids = new ArrayList<>();
        if(depts != null && depts.size() > 0){
            for (Dept dept : depts) {
                deptids.add(dept.getId());
            }
        }
        return deptids;
    }
    /**
     * 获取所有父部门id
     */
    @Override
    public List<Integer> getParentDeptIds(Integer deptid) {
        Dept dept = deptMapper.selectById(deptid);
        String pids = dept.getPids();
        String[] split = pids.split(",");
        ArrayList<Integer> parentDeptIds = new ArrayList<>();
        for (String s : split) {
            parentDeptIds.add(Integer.valueOf(StrKit.removeSuffix(StrKit.removePrefix(s, "["), "]")));
        }
        return parentDeptIds;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/IConstantFactory.java
New file
@@ -0,0 +1,116 @@
package com.stylefeng.guns.core.common.constant.factory;
import com.stylefeng.guns.modular.system.model.Dict;
import java.util.List;
/**
 * 常量生产工厂的接口
 *
 * @author fengshuonan
 * @date 2017-06-14 21:12
 */
public interface IConstantFactory {
    /**
     * 根据用户id获取用户名称
     *
     * @author stylefeng
     * @Date 2017/5/9 23:41
     */
    String getUserNameById(Integer userId);
    /**
     * 根据用户id获取用户账号
     *
     * @author stylefeng
     * @date 2017年5月16日21:55:371
     */
    String getUserAccountById(Integer userId);
    /**
     * 通过角色ids获取角色名称
     */
    String getRoleName(String roleIds);
    /**
     * 通过角色id获取角色名称
     */
    String getSingleRoleName(Integer roleId);
    /**
     * 通过角色id获取角色英文名称
     */
    String getSingleRoleTip(Integer roleId);
    /**
     * 获取部门名称
     */
    String getDeptName(Integer deptId);
    /**
     * 获取菜单的名称们(多个)
     */
    String getMenuNames(String menuIds);
    /**
     * 获取菜单名称
     */
    String getMenuName(Long menuId);
    /**
     * 获取菜单名称通过编号
     */
    String getMenuNameByCode(String code);
    /**
     * 获取字典名称
     */
    String getDictName(Integer dictId);
    /**
     * 获取通知标题
     */
    String getNoticeTitle(Integer dictId);
    /**
     * 根据字典名称和字典中的值获取对应的名称
     */
    String getDictsByName(String name, Integer val);
    /**
     * 获取性别名称
     */
    String getSexName(Integer sex);
    /**
     * 获取用户登录状态
     */
    String getStatusName(Integer status);
    /**
     * 获取菜单状态
     */
    String getMenuStatusName(Integer status);
    /**
     * 查询字典
     */
    List<Dict> findInDict(Integer id);
    /**
     * 获取被缓存的对象(用户删除业务)
     */
    String getCacheObject(String para);
    /**
     * 获取子部门id
     */
    List<Integer> getSubDeptId(Integer deptid);
    /**
     * 获取所有父部门id
     */
    List<Integer> getParentDeptIds(Integer deptid);
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/MutiStrFactory.java
New file
@@ -0,0 +1,96 @@
package com.stylefeng.guns.core.common.constant.factory;
import com.stylefeng.guns.core.support.StrKit;
import com.stylefeng.guns.core.util.ToolUtil;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 组合字符串生产者
 *
 * @author fengshuonan
 * @date 2017-04-27 16:42
 */
public class MutiStrFactory {
    /**
     * 每个条目之间的分隔符
     */
    public static final String ITEM_SPLIT = ";";
    /**
     * 属性之间的分隔符
     */
    public static final String ATTR_SPLIT = ":";
    /**
     * 拼接字符串的id
     */
    public static final String MUTI_STR_ID = "ID";
    /**
     * 拼接字符串的CODE
     */
    public static final String MUTI_STR_CODE = "CODE";
    /**
     * 拼接字符串的NAME
     */
    public static final String MUTI_STR_NAME = "NAME";
    /**
     * 拼接字符串的NUM
     */
    public static final String MUTI_STR_NUM = "NUM";
    /**
     * 解析一个组合字符串(例如:  "1:启用;2:禁用;3:冻结"  这样的字符串)
     *
     * @author fengshuonan
     * @Date 2017/4/27 16:44
     */
    public static List<Map<String,String>> parseKeyValue(String mutiString){
        if(ToolUtil.isEmpty(mutiString)){
            return new ArrayList<>();
        }else{
            ArrayList<Map<String,String>> results = new ArrayList<>();
            String[] items = StrKit.split(StrKit.removeSuffix(mutiString, ITEM_SPLIT), ITEM_SPLIT);
            for (String item : items) {
                String[] attrs = item.split(ATTR_SPLIT);
                HashMap<String, String> itemMap = new HashMap<>();
                itemMap.put(MUTI_STR_CODE,attrs[0]);
                itemMap.put(MUTI_STR_NAME,attrs[1]);
                itemMap.put(MUTI_STR_NUM,attrs[2]);
                results.add(itemMap);
            }
            return results;
        }
    }
    /**
     * 解析id:key:value这样类型的字符串
     *
     * @author fengshuonan
     * @Date 2017/4/28 11:06
     */
    public static List<Map<String,String>> parseIdKeyValue(String mutiString){
        if(ToolUtil.isEmpty(mutiString)){
            return new ArrayList<>();
        }else{
            ArrayList<Map<String,String>> results = new ArrayList<>();
            String[] items = StrKit.split(StrKit.removeSuffix(mutiString, ITEM_SPLIT), ITEM_SPLIT);
            for (String item : items) {
                String[] attrs = item.split(ATTR_SPLIT);
                HashMap<String, String> itemMap = new HashMap<>();
                itemMap.put(MUTI_STR_CODE,attrs[0]);
                itemMap.put(MUTI_STR_NAME,attrs[1]);
                itemMap.put(MUTI_STR_NUM,attrs[2]);
                results.add(itemMap);
            }
            return results;
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/factory/PageFactory.java
New file
@@ -0,0 +1,38 @@
package com.stylefeng.guns.core.common.constant.factory;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.core.common.constant.state.Order;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.ToolUtil;
import javax.servlet.http.HttpServletRequest;
/**
 * BootStrap Table默认的分页参数创建
 *
 * @author fengshuonan
 * @date 2017-04-05 22:25
 */
public class PageFactory<T> {
    public Page<T> defaultPage() {
        HttpServletRequest request = HttpKit.getRequest();
        int limit = Integer.valueOf(request.getParameter("limit"));     //每页多少条数据
        int offset = Integer.valueOf(request.getParameter("offset"));   //每页的偏移量(本页当前有多少条)
        String sort = request.getParameter("sort");         //排序字段名称
        String order = request.getParameter("order");       //asc或desc(升序或降序)
        if (ToolUtil.isEmpty(sort)) {
            Page<T> page = new Page<>((offset / limit + 1), limit);
            page.setOpenSort(false);
            return page;
        } else {
            Page<T> page = new Page<>((offset / limit + 1), limit, sort);
            if (Order.ASC.getDes().equals(order)) {
                page.setAsc(true);
            } else {
                page.setAsc(false);
            }
            return page;
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/BizLogType.java
New file
@@ -0,0 +1,51 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 业务日志类型
 *
 * @author fengshuonan
 * @Date 2017年1月22日 下午12:14:59
 */
public enum BizLogType {
    ALL(0, null),//全部日志
    BUSSINESS(1, "业务日志"),
    EXCEPTION(2, "异常日志");
    Integer val;
    String message;
    BizLogType(Integer val, String message) {
        this.val = val;
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public Integer getVal() {
        return val;
    }
    public void setVal(Integer val) {
        this.val = val;
    }
    public static String valueOf(Integer value) {
        if (value == null) {
            return null;
        } else {
            for (BizLogType bizLogType : BizLogType.values()) {
                if (bizLogType.getVal().equals(value)) {
                    return bizLogType.getMessage();
                }
            }
            return null;
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/ExpenseState.java
New file
@@ -0,0 +1,52 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 是否是菜单的枚举
 *
 * @author fengshuonan
 * @date 2017年6月1日22:50:11
 */
public enum ExpenseState {
    SUBMITING(1, "待提交"),
    CHECKING(2, "待审核"),
    PASS(3, "审核通过"),
    UN_PASS(4, "未通过");
    int code;
    String message;
    ExpenseState(int code, String message) {
        this.code = code;
        this.message = message;
    }
    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 static String valueOf(Integer status) {
        if (status == null) {
            return "";
        } else {
            for (ExpenseState s : ExpenseState.values()) {
                if (s.getCode() == status) {
                    return s.getMessage();
                }
            }
            return "";
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/LogSucceed.java
New file
@@ -0,0 +1,27 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 业务是否成功的日志记录
 *
 * @author fengshuonan
 * @Date 2017年1月22日 下午12:14:59
 */
public enum LogSucceed {
    SUCCESS("成功"),
    FAIL("失败");
    String message;
    LogSucceed(String message) {
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/LogType.java
New file
@@ -0,0 +1,30 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 日志类型
 *
 * @author fengshuonan
 * @Date 2017年1月22日 下午12:14:59
 */
public enum LogType {
    LOGIN("登录日志"),
    LOGIN_FAIL("登录失败日志"),
    EXIT("退出日志"),
    EXCEPTION("异常日志"),
    BUSSINESS("业务日志");
    String message;
    LogType(String message) {
        this.message = message;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/ManagerStatus.java
New file
@@ -0,0 +1,49 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 管理员的状态
 *
 * @author fengshuonan
 * @Date 2017年1月10日 下午9:54:13
 */
public enum ManagerStatus {
    OK(1, "启用"), FREEZED(2, "冻结"), DELETED(3, "被删除");
    int code;
    String message;
    ManagerStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }
    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 static String valueOf(Integer value) {
        if (value == null) {
            return "";
        } else {
            for (ManagerStatus ms : ManagerStatus.values()) {
                if (ms.getCode() == value) {
                    return ms.getMessage();
                }
            }
            return "";
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/MenuOpenStatus.java
New file
@@ -0,0 +1,50 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 菜单是否打开的状态
 *
 * @author fengshuonan
 * @Date 2017年4月8日10:12:15
 */
public enum MenuOpenStatus {
    OPEN(1, "打开"),
    CLOSE(0, "关闭");
    int code;
    String message;
    MenuOpenStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }
    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 static String valueOf(Integer status) {
        if (status == null) {
            return "";
        } else {
            for (MenuOpenStatus s : MenuOpenStatus.values()) {
                if (s.getCode() == status) {
                    return s.getMessage();
                }
            }
            return "";
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/MenuStatus.java
New file
@@ -0,0 +1,50 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 菜单的状态
 *
 * @author fengshuonan
 * @Date 2017年1月22日 下午12:14:59
 */
public enum MenuStatus {
    ENABLE(1, "启用"),
    DISABLE(0, "禁用");
    int code;
    String message;
    MenuStatus(int code, String message) {
        this.code = code;
        this.message = message;
    }
    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 static String valueOf(Integer status) {
        if (status == null) {
            return "";
        } else {
            for (MenuStatus s : MenuStatus.values()) {
                if (s.getCode() == status) {
                    return s.getMessage();
                }
            }
            return "";
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/constant/state/Order.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.core.common.constant.state;
/**
 * 数据库排序
 *
 * @author fengshuonan
 * @Date 2017年5月31日20:48:41
 */
public enum Order {
    ASC("asc"), DESC("desc");
    private String des;
    Order(String des) {
        this.des = des;
    }
    public String getDes() {
        return des;
    }
    public void setDes(String des) {
        this.des = des;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/BizExceptionEnum.java
New file
@@ -0,0 +1,100 @@
package com.stylefeng.guns.core.common.exception;
import com.stylefeng.guns.core.exception.ServiceExceptionEnum;
/**
 * @author fengshuonan
 * @Description 所有业务异常的枚举
 * @date 2016年11月12日 下午5:04:51
 */
public enum BizExceptionEnum implements ServiceExceptionEnum {
    /**
     * 字典
     */
    DICT_EXISTED(400, "字典已经存在"),
    ERROR_CREATE_DICT(500, "创建字典失败"),
    ERROR_WRAPPER_FIELD(500, "包装字典属性失败"),
    ERROR_CODE_EMPTY(500, "字典类型不能为空"),
    /**
     * 文件上传
     */
    FILE_READING_ERROR(400, "FILE_READING_ERROR!"),
    FILE_NOT_FOUND(400, "FILE_NOT_FOUND!"),
    UPLOAD_ERROR(500, "上传图片出错"),
    /**
     * 权限和数据问题
     */
    DB_RESOURCE_NULL(400, "数据库中没有该资源"),
    NO_PERMITION(405, "权限异常"),
    REQUEST_INVALIDATE(400, "请求数据格式不正确"),
    INVALID_KAPTCHA(400, "验证码不正确"),
    CANT_DELETE_ADMIN(600, "不能删除超级管理员"),
    CANT_FREEZE_ADMIN(600, "不能冻结超级管理员"),
    CANT_CHANGE_ADMIN(600, "不能修改超级管理员角色"),
    /**
     * 账户问题
     */
    USER_ALREADY_REG(401, "该用户已经注册"),
    NO_THIS_USER(400, "没有此用户"),
    USER_NOT_EXISTED(400, "没有此用户"),
    ACCOUNT_FREEZED(401, "账号被冻结"),
    OLD_PWD_NOT_RIGHT(402, "原密码不正确"),
    TWO_PWD_NOT_MATCH(405, "两次输入密码不一致"),
    /**
     * 错误的请求
     */
    MENU_PCODE_COINCIDENCE(400, "菜单编号和副编号不能一致"),
    EXISTED_THE_MENU(400, "菜单编号重复,不能添加"),
    DICT_MUST_BE_NUMBER(400, "字典的值必须为数字"),
    REQUEST_NULL(400, "请求有错误"),
    SESSION_TIMEOUT(400, "会话超时"),
    SERVER_ERROR(500, "服务器异常"),
    /**
     * token异常
     */
    TOKEN_EXPIRED(600, "token过期"),
    TOKEN_ERROR(600, "token验证失败"),
    /**
     * 签名异常
     */
    SIGN_ERROR(700, "签名验证失败"),
    /**
     * 其他
     */
    AUTH_REQUEST_ERROR(400, "账号密码错误");
    BizExceptionEnum(int code, String message) {
        this.code = code;
        this.message = message;
    }
    private Integer code;
    private String message;
    @Override
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    @Override
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/common/exception/InvalidKaptchaException.java
New file
@@ -0,0 +1,10 @@
package com.stylefeng.guns.core.common.exception;
/**
 * 验证码错误异常
 *
 * @author fengshuonan
 * @date 2017-05-05 23:52
 */
public class InvalidKaptchaException extends RuntimeException {
}
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/GunsUserFilter.java
New file
@@ -0,0 +1,105 @@
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package com.stylefeng.guns.core.intercept;
import com.stylefeng.guns.core.shiro.ShiroKit;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Filter that allows access to resources if the accessor is a known user, which is defined as
 * having a known principal.  This means that any user who is authenticated or remembered via a
 * 'remember me' feature will be allowed access from this filter.
 * <p/>
 * If the accessor is not a known user, then they will be redirected to the {@link #setLoginUrl(String) loginUrl}</p>
 *
 * @since 0.9
 */
public class GunsUserFilter extends AccessControlFilter {
    /**
     * Returns <code>true</code> if the request is a
     * {@link #isLoginRequest(javax.servlet.ServletRequest, javax.servlet.ServletResponse) loginRequest} or
     * if the current {@link #getSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) subject}
     * is not <code>null</code>, <code>false</code> otherwise.
     *
     * @return <code>true</code> if the request is a
     * {@link #isLoginRequest(javax.servlet.ServletRequest, javax.servlet.ServletResponse) loginRequest} or
     * if the current {@link #getSubject(javax.servlet.ServletRequest, javax.servlet.ServletResponse) subject}
     * is not <code>null</code>, <code>false</code> otherwise.
     */
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
        if (isLoginRequest(request, response)) {
            return true;
        } else {
            Subject subject = getSubject(request, response);
            // If principal is not null, then the user is known and should be allowed access.
            return subject.getPrincipal() != null;
        }
    }
    /**
     * This default implementation simply calls
     * {@link #saveRequestAndRedirectToLogin(javax.servlet.ServletRequest, javax.servlet.ServletResponse) saveRequestAndRedirectToLogin}
     * and then immediately returns <code>false</code>, thereby preventing the chain from continuing so the redirect may
     * execute.
     */
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        HttpServletRequest httpServletRequest = WebUtils.toHttp(request);
        HttpServletResponse httpServletResponse = WebUtils.toHttp(response);
        /**
         * 如果是ajax请求则不进行跳转
         */
        if (httpServletRequest.getHeader("x-requested-with") != null
                && httpServletRequest.getHeader("x-requested-with").equalsIgnoreCase("XMLHttpRequest")) {
            httpServletResponse.setHeader("sessionstatus", "timeout");
            return false;
        } else {
            /**
             * 第一次点击页面
             */
            String referer = httpServletRequest.getHeader("Referer");
            if (referer == null) {
                saveRequestAndRedirectToLogin(request, response);
                return false;
            } else {
                /**
                 * 从别的页面跳转过来的
                 */
                if (ShiroKit.getSession().getAttribute("sessionFlag") == null) {
                    httpServletRequest.setAttribute("tips", "session超时");
                    httpServletRequest.getRequestDispatcher("/login").forward(request, response);
                    return false;
                } else {
                    saveRequestAndRedirectToLogin(request, response);
                    return false;
                }
            }
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/RestApiInteceptor.java
New file
@@ -0,0 +1,90 @@
package com.stylefeng.guns.core.intercept;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.common.constant.JwtConstants;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.util.JwtTokenUtil;
import com.stylefeng.guns.core.util.RenderUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.util.RedisUtil;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.util.SpringUtil;
import io.jsonwebtoken.JwtException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * Rest Api接口鉴权
 *
 * @author stylefeng
 * @Date 2018/7/20 23:11
 */
public class RestApiInteceptor extends HandlerInterceptorAdapter {
    @Autowired
    private RedisUtil redisUtil = SpringUtil.getObject(RedisUtil.class);
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof org.springframework.web.servlet.resource.ResourceHttpRequestHandler) {
            return true;
        }
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        return check(request, response, handlerMethod);
    }
    private boolean check(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) {
        String servletPath = request.getServletPath();
        if (servletPath.equals(JwtConstants.AUTH_PATH)) {
            return true;
        }
        final String requestHeader = request.getHeader(JwtConstants.AUTH_HEADER);
        String authToken;
        if (requestHeader != null && requestHeader.startsWith("Bearer ")) {
            authToken = requestHeader.substring(7);
            //验证token是否过期,包含了验证jwt是否正确
            try {
                boolean flag = JwtTokenUtil.isTokenExpired(authToken);
                if (flag) {
                    RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_EXPIRED.getCode(), BizExceptionEnum.TOKEN_EXPIRED.getMessage()));
                    return false;
                }
            } catch (JwtException e) {
                //有异常就是token解析失败
                RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
                return false;
            }
        } else {
            if(servletPath.indexOf("/auth/") == 0){
                return true;
            }
            //header没有带Bearer字段
            RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
            return false;
        }
        /**
         * 根据token返回用户id
         */
        String key = null;
        int length = authToken.length();
        if(length > 16){
            key = authToken.substring(length - 16);
        }else{
            key = authToken;
        }
        String value = redisUtil.getValue(key);
        if(ToolUtil.isEmpty(value)){
            RenderUtil.renderJson(response, ResultUtil.tokenErr());
            return false;
        }
        return true;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/intercept/SessionHolderInterceptor.java
New file
@@ -0,0 +1,34 @@
package com.stylefeng.guns.core.intercept;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.util.HttpSessionHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
 * 静态调用session的拦截器
 *
 * @author fengshuonan
 * @date 2016年11月13日 下午10:15:42
 */
@Aspect
@Component
public class SessionHolderInterceptor extends BaseController {
    @Pointcut("execution(* com.stylefeng.guns.*..controller.*.*(..))")
    public void cutService() {
    }
    @Around("cutService()")
    public Object sessionKit(ProceedingJoinPoint point) throws Throwable {
        HttpSessionHolder.put(super.getHttpServletRequest().getSession());
        try {
            return point.proceed();
        } finally {
            HttpSessionHolder.remove();
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/listener/ConfigListener.java
New file
@@ -0,0 +1,54 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.listener;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.util.HashMap;
import java.util.Map;
/**
 * ServletContext监听器
 *
 * @author stylefeng
 * @Date 2018/2/22 21:07
 */
public class ConfigListener implements ServletContextListener {
    private static Map<String, String> conf = new HashMap<>();
    public static Map<String, String> getConf() {
        return conf;
    }
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        conf.clear();
    }
    @Override
    public void contextInitialized(ServletContextEvent evt) {
        ServletContext sc = evt.getServletContext();
        //项目发布,当前运行环境的绝对路径
        conf.put("realPath", sc.getRealPath("/").replaceFirst("/", ""));
        //servletContextPath,默认""
        conf.put("contextPath", sc.getContextPath());
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/log/LogManager.java
New file
@@ -0,0 +1,33 @@
package com.stylefeng.guns.core.log;
import java.util.TimerTask;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
 * 日志管理器
 *
 * @author fengshuonan
 * @date 2017-03-30 16:29
 */
public class LogManager {
    //日志记录操作延时
    private final int OPERATE_DELAY_TIME = 10;
    //异步操作记录日志的线程池
    private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
    private LogManager() {
    }
    public static LogManager logManager = new LogManager();
    public static LogManager me() {
        return logManager;
    }
    public void executeLog(TimerTask task) {
        executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/log/LogObjectHolder.java
New file
@@ -0,0 +1,34 @@
package com.stylefeng.guns.core.log;
import com.stylefeng.guns.core.util.SpringContextHolder;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;
import java.io.Serializable;
/**
 * 被修改的bean临时存放的地方
 *
 * @author fengshuonan
 * @date 2017-03-31 11:19
 */
@Component
@Scope(scopeName = WebApplicationContext.SCOPE_SESSION)
public class LogObjectHolder implements Serializable{
    private Object object = null;
    public void set(Object obj) {
        this.object = obj;
    }
    public Object get() {
        return object;
    }
    public static LogObjectHolder me(){
        LogObjectHolder bean = SpringContextHolder.getBean(LogObjectHolder.class);
        return bean;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/log/factory/LogFactory.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.core.log.factory;
import com.stylefeng.guns.core.common.constant.state.LogSucceed;
import com.stylefeng.guns.core.common.constant.state.LogType;
import com.stylefeng.guns.modular.system.model.LoginLog;
import com.stylefeng.guns.modular.system.model.OperationLog;
import java.util.Date;
/**
 * 日志对象创建工厂
 *
 * @author fengshuonan
 * @date 2016年12月6日 下午9:18:27
 */
public class LogFactory {
    /**
     * 创建操作日志
     */
    public static OperationLog createOperationLog(LogType logType, Integer userId, String bussinessName, String clazzName, String methodName, String msg, LogSucceed succeed) {
        OperationLog operationLog = new OperationLog();
        operationLog.setLogtype(logType.getMessage());
        operationLog.setLogname(bussinessName);
        operationLog.setUserid(userId);
        operationLog.setClassname(clazzName);
        operationLog.setMethod(methodName);
        operationLog.setCreatetime(new Date());
        operationLog.setSucceed(succeed.getMessage());
        operationLog.setMessage(msg);
        return operationLog;
    }
    /**
     * 创建登录日志
     */
    public static LoginLog createLoginLog(LogType logType, Integer userId, String msg, String ip) {
        LoginLog loginLog = new LoginLog();
        loginLog.setLogname(logType.getMessage());
        loginLog.setUserid(userId);
        loginLog.setCreatetime(new Date());
        loginLog.setSucceed(LogSucceed.SUCCESS.getMessage());
        loginLog.setIp(ip);
        loginLog.setMessage(msg);
        return loginLog;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/log/factory/LogTaskFactory.java
New file
@@ -0,0 +1,102 @@
package com.stylefeng.guns.core.log.factory;
import com.stylefeng.guns.core.common.constant.state.LogSucceed;
import com.stylefeng.guns.core.common.constant.state.LogType;
import com.stylefeng.guns.modular.system.dao.LoginLogMapper;
import com.stylefeng.guns.modular.system.dao.OperationLogMapper;
import com.stylefeng.guns.modular.system.model.LoginLog;
import com.stylefeng.guns.modular.system.model.OperationLog;
import com.stylefeng.guns.core.db.Db;
import com.stylefeng.guns.core.log.LogManager;
import com.stylefeng.guns.core.util.ToolUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.TimerTask;
/**
 * 日志操作任务创建工厂
 *
 * @author fengshuonan
 * @date 2016年12月6日 下午9:18:27
 */
public class LogTaskFactory {
    private static Logger logger = LoggerFactory.getLogger(LogManager.class);
    private static LoginLogMapper loginLogMapper = Db.getMapper(LoginLogMapper.class);
    private static OperationLogMapper operationLogMapper = Db.getMapper(OperationLogMapper.class);
    public static TimerTask loginLog(final Integer userId, final String ip) {
        return new TimerTask() {
            @Override
            public void run() {
                try {
                    LoginLog loginLog = LogFactory.createLoginLog(LogType.LOGIN, userId, null, ip);
                    loginLogMapper.insert(loginLog);
                } catch (Exception e) {
                    logger.error("创建登录日志异常!", e);
                }
            }
        };
    }
    public static TimerTask loginLog(final String username, final String msg, final String ip) {
        return new TimerTask() {
            @Override
            public void run() {
                LoginLog loginLog = LogFactory.createLoginLog(
                        LogType.LOGIN_FAIL, null, "账号:" + username + "," + msg, ip);
                try {
                    loginLogMapper.insert(loginLog);
                } catch (Exception e) {
                    logger.error("创建登录失败异常!", e);
                }
            }
        };
    }
    public static TimerTask exitLog(final Integer userId, final String ip) {
        return new TimerTask() {
            @Override
            public void run() {
                LoginLog loginLog = LogFactory.createLoginLog(LogType.EXIT, userId, null,ip);
                try {
                    loginLogMapper.insert(loginLog);
                } catch (Exception e) {
                    logger.error("创建退出日志异常!", e);
                }
            }
        };
    }
    public static TimerTask bussinessLog(final Integer userId, final String bussinessName, final String clazzName, final String methodName, final String msg) {
        return new TimerTask() {
            @Override
            public void run() {
                OperationLog operationLog = LogFactory.createOperationLog(
                        LogType.BUSSINESS, userId, bussinessName, clazzName, methodName, msg, LogSucceed.SUCCESS);
                try {
                    operationLogMapper.insert(operationLog);
                } catch (Exception e) {
                    logger.error("创建业务日志异常!", e);
                }
            }
        };
    }
    public static TimerTask exceptionLog(final Integer userId, final Exception exception) {
        return new TimerTask() {
            @Override
            public void run() {
                String msg = ToolUtil.getExceptionMsg(exception);
                OperationLog operationLog = LogFactory.createOperationLog(
                        LogType.EXCEPTION, userId, "", null, null, msg, LogSucceed.FAIL);
                try {
                    operationLogMapper.insert(operationLog);
                } catch (Exception e) {
                    logger.error("创建异常日志异常!", e);
                }
            }
        };
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroDbRealm.java
New file
@@ -0,0 +1,78 @@
package com.stylefeng.guns.core.shiro;
import com.stylefeng.guns.core.shiro.factory.IShiro;
import com.stylefeng.guns.core.shiro.factory.ShiroFactroy;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ShiroDbRealm extends AuthorizingRealm {
    /**
     * 登录认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken)
            throws AuthenticationException {
        IShiro shiroFactory = ShiroFactroy.me();
        UsernamePasswordToken token = (UsernamePasswordToken) authcToken;
        User user = shiroFactory.user(token.getUsername());
        ShiroUser shiroUser = shiroFactory.shiroUser(user);
        return shiroFactory.info(shiroUser, user, super.getName());
    }
    /**
     * 权限认证
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        IShiro shiroFactory = ShiroFactroy.me();
        ShiroUser shiroUser = (ShiroUser) principals.getPrimaryPrincipal();
        List<Integer> roleList = shiroUser.getRoleList();
        Set<String> permissionSet = new HashSet<>();
        Set<String> roleNameSet = new HashSet<>();
        for (Integer roleId : roleList) {
            List<String> permissions = shiroFactory.findPermissionsByRoleId(roleId);
            if (permissions != null) {
                for (String permission : permissions) {
                    if (ToolUtil.isNotEmpty(permission)) {
                        permissionSet.add(permission);
                    }
                }
            }
            String roleName = shiroFactory.findRoleNameByRoleId(roleId);
            roleNameSet.add(roleName);
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addStringPermissions(permissionSet);
        info.addRoles(roleNameSet);
        return info;
    }
    /**
     * 设置认证加密方式
     */
    @Override
    public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
        super.setCredentialsMatcher(md5CredentialsMatcher);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroKit.java
New file
@@ -0,0 +1,290 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.shiro;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.util.ToolUtil;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import java.util.List;
/**
 * shiro工具类
 *
 * @author dafei, Chill Zhuang
 */
public class ShiroKit {
    private static final String NAMES_DELIMETER = ",";
    /**
     * 加盐参数
     */
    public final static String hashAlgorithmName = "MD5";
    /**
     * 循环次数
     */
    public final static int hashIterations = 1024;
    /**
     * shiro密码加密工具类
     *
     * @param credentials 密码
     * @param saltSource 密码盐
     * @return
     */
    public static String md5(String credentials, String saltSource) {
        ByteSource salt = new Md5Hash(saltSource);
        return new SimpleHash(hashAlgorithmName, credentials, salt, hashIterations).toString();
    }
    /**
     * 获取随机盐值
     * @param length
     * @return
     */
    public static String getRandomSalt(int length) {
        return ToolUtil.getRandomString(length);
    }
    /**
     * 获取当前 Subject
     *
     * @return Subject
     */
    public static Subject getSubject() {
        return SecurityUtils.getSubject();
    }
    /**
     * 获取封装的 ShiroUser
     *
     * @return ShiroUser
     */
    public static ShiroUser getUser() {
        if (isGuest()) {
            return null;
        } else {
            return (ShiroUser) getSubject().getPrincipals().getPrimaryPrincipal();
        }
    }
    /**
     * 从shiro获取session
     *
     */
    public static Session getSession() {
        return getSubject().getSession();
    }
    /**
     * 获取shiro指定的sessionKey
     *
     */
    @SuppressWarnings("unchecked")
    public static <T> T getSessionAttr(String key) {
        Session session = getSession();
        return session != null ? (T) session.getAttribute(key) : null;
    }
    /**
     * 设置shiro指定的sessionKey
     *
     */
    public static void setSessionAttr(String key, Object value) {
        Session session = getSession();
        session.setAttribute(key, value);
    }
    /**
     * 移除shiro指定的sessionKey
     */
    public static void removeSessionAttr(String key) {
        Session session = getSession();
        if (session != null)
            session.removeAttribute(key);
    }
    /**
     * 验证当前用户是否属于该角色?,使用时与lacksRole 搭配使用
     *
     * @param roleName
     *            角色名
     * @return 属于该角色:true,否则false
     */
    public static boolean hasRole(String roleName) {
        return getSubject() != null && roleName != null
                && roleName.length() > 0 && getSubject().hasRole(roleName);
    }
    /**
     * 与hasRole标签逻辑相反,当用户不属于该角色时验证通过。
     *
     * @param roleName
     *            角色名
     * @return 不属于该角色:true,否则false
     */
    public static boolean lacksRole(String roleName) {
        return !hasRole(roleName);
    }
    /**
     * 验证当前用户是否属于以下任意一个角色。
     *
     * @param roleNames
     *            角色列表
     * @return 属于:true,否则false
     */
    public static boolean hasAnyRoles(String roleNames) {
        boolean hasAnyRole = false;
        Subject subject = getSubject();
        if (subject != null && roleNames != null && roleNames.length() > 0) {
            for (String role : roleNames.split(NAMES_DELIMETER)) {
                if (subject.hasRole(role.trim())) {
                    hasAnyRole = true;
                    break;
                }
            }
        }
        return hasAnyRole;
    }
    /**
     * 验证当前用户是否属于以下所有角色。
     *
     * @param roleNames
     *            角色列表
     * @return 属于:true,否则false
     */
    public static boolean hasAllRoles(String roleNames) {
        boolean hasAllRole = true;
        Subject subject = getSubject();
        if (subject != null && roleNames != null && roleNames.length() > 0) {
            for (String role : roleNames.split(NAMES_DELIMETER)) {
                if (!subject.hasRole(role.trim())) {
                    hasAllRole = false;
                    break;
                }
            }
        }
        return hasAllRole;
    }
    /**
     * 验证当前用户是否拥有指定权限,使用时与lacksPermission 搭配使用
     *
     * @param permission
     *            权限名
     * @return 拥有权限:true,否则false
     */
    public static boolean hasPermission(String permission) {
        return getSubject() != null && permission != null
                && permission.length() > 0
                && getSubject().isPermitted(permission);
    }
    /**
     * 与hasPermission标签逻辑相反,当前用户没有制定权限时,验证通过。
     *
     * @param permission
     *            权限名
     * @return 拥有权限:true,否则false
     */
    public static boolean lacksPermission(String permission) {
        return !hasPermission(permission);
    }
    /**
     * 已认证通过的用户。不包含已记住的用户,这是与user标签的区别所在。与notAuthenticated搭配使用
     *
     * @return 通过身份验证:true,否则false
     */
    public static boolean isAuthenticated() {
        return getSubject() != null && getSubject().isAuthenticated();
    }
    /**
     * 未认证通过用户,与authenticated标签相对应。与guest标签的区别是,该标签包含已记住用户。。
     *
     * @return 没有通过身份验证:true,否则false
     */
    public static boolean notAuthenticated() {
        return !isAuthenticated();
    }
    /**
     * 认证通过或已记住的用户。与guset搭配使用。
     *
     * @return 用户:true,否则 false
     */
    public static boolean isUser() {
        return getSubject() != null && getSubject().getPrincipal() != null;
    }
    /**
     * 验证当前用户是否为“访客”,即未认证(包含未记住)的用户。用user搭配使用
     *
     * @return 访客:true,否则false
     */
    public static boolean isGuest() {
        return !isUser();
    }
    /**
     * 输出当前用户信息,通常为登录帐号信息。
     *
     * @return 当前用户信息
     */
    public static String principal() {
        if (getSubject() != null) {
            Object principal = getSubject().getPrincipal();
            return principal.toString();
        }
        return "";
    }
    /**
     * 获取当前用户的部门数据范围的集合
     */
    public static List<Integer> getDeptDataScope() {
        Integer deptId = getUser().getDeptId();
        List<Integer> subDeptIds = ConstantFactory.me().getSubDeptId(deptId);
        subDeptIds.add(deptId);
        return subDeptIds;
    }
    /**
     * 判断当前用户是否是超级管理员
     */
    public static boolean isAdmin() {
        List<Integer> roleList = ShiroKit.getUser().getRoleList();
        for (Integer integer : roleList) {
            String singleRoleTip = ConstantFactory.me().getSingleRoleTip(integer);
            if (singleRoleTip.equals(Const.ADMIN_NAME)) {
                return true;
            }
        }
        return false;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/ShiroUser.java
New file
@@ -0,0 +1,81 @@
package com.stylefeng.guns.core.shiro;
import java.io.Serializable;
import java.util.List;
/**
 * 自定义Authentication对象,使得Subject除了携带用户的登录名外还可以携带更多信息
 *
 * @author fengshuonan
 * @date 2016年12月5日 上午10:26:43
 */
public class ShiroUser implements Serializable {
    private static final long serialVersionUID = 1L;
    public Integer id;          // 主键ID
    public String account;      // 账号
    public String name;         // 姓名
    public Integer deptId;      // 部门id
    public List<Integer> roleList; // 角色集
    public String deptName;        // 部门名称
    public List<String> roleNames; // 角色名称集
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getDeptId() {
        return deptId;
    }
    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }
    public List<Integer> getRoleList() {
        return roleList;
    }
    public void setRoleList(List<Integer> roleList) {
        this.roleList = roleList;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public List<String> getRoleNames() {
        return roleNames;
    }
    public void setRoleNames(List<String> roleNames) {
        this.roleNames = roleNames;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/ICheck.java
New file
@@ -0,0 +1,32 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.shiro.check;
/**
 * 检查用接口
 */
public interface ICheck {
    /**
     * 检查当前登录用户是否拥有指定的角色访问当
     */
    boolean check(Object[] permissions);
    /**
     * 检查当前登录用户是否拥有当前请求的servlet的权限
     */
    boolean checkAll();
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/PermissionCheckFactory.java
New file
@@ -0,0 +1,73 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.shiro.check;
import com.stylefeng.guns.core.listener.ConfigListener;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.support.CollectionKit;
import com.stylefeng.guns.core.support.HttpKit;
import com.stylefeng.guns.core.util.SpringContextHolder;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
/**
 * 权限自定义检查
 */
@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class PermissionCheckFactory implements ICheck {
    public static ICheck me() {
        return SpringContextHolder.getBean(ICheck.class);
    }
    @Override
    public boolean check(Object[] permissions) {
        ShiroUser user = ShiroKit.getUser();
        if (null == user) {
            return false;
        }
        String join = CollectionKit.join(permissions, ",");
        if (ShiroKit.hasAnyRoles(join)) {
            return true;
        }
        return false;
    }
    @Override
    public boolean checkAll() {
        HttpServletRequest request = HttpKit.getRequest();
        ShiroUser user = ShiroKit.getUser();
        if (null == user) {
            return false;
        }
        String requestURI = request.getRequestURI().replaceFirst(ConfigListener.getConf().get("contextPath"), "");
        String[] str = requestURI.split("/");
        if (str.length > 3) {
            requestURI = "/" + str[1] + "/" + str[2];
        }
        if (ShiroKit.hasPermission(requestURI)) {
            return true;
        }
        return false;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/check/PermissionCheckManager.java
New file
@@ -0,0 +1,50 @@
/**
 * Copyright (c) 2015-2017, Chill Zhuang 庄骞 (smallchill@163.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.stylefeng.guns.core.shiro.check;
import com.stylefeng.guns.core.util.SpringContextHolder;
/**
 * 权限检查管理器(入口)
 */
public class PermissionCheckManager {
    private final static PermissionCheckManager me = new PermissionCheckManager();
    private ICheck defaultCheckFactory = SpringContextHolder.getBean(ICheck.class);
    public static PermissionCheckManager me() {
        return me;
    }
    private PermissionCheckManager() {
    }
    public PermissionCheckManager(ICheck checkFactory) {
        this.defaultCheckFactory = checkFactory;
    }
    public void setDefaultCheckFactory(ICheck defaultCheckFactory) {
        this.defaultCheckFactory = defaultCheckFactory;
    }
    public static boolean check(Object[] permissions) {
        return me.defaultCheckFactory.check(permissions);
    }
    public static boolean checkAll() {
        return me.defaultCheckFactory.checkAll();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/factory/IShiro.java
New file
@@ -0,0 +1,50 @@
package com.stylefeng.guns.core.shiro.factory;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import java.util.List;
/**
 * 定义shirorealm所需数据的接口
 *
 * @author fengshuonan
 * @date 2016年12月5日 上午10:23:34
 */
public interface IShiro {
    /**
     * 根据账号获取登录用户
     *
     * @param account 账号
     */
    User user(String account);
    /**
     * 根据系统用户获取Shiro的用户
     *
     * @param user 系统用户
     */
    ShiroUser shiroUser(User user);
    /**
     * 获取权限列表通过角色id
     *
     * @param roleId 角色id
     */
    List<String> findPermissionsByRoleId(Integer roleId);
    /**
     * 根据角色id获取角色名称
     *
     * @param roleId 角色id
     */
    String findRoleNameByRoleId(Integer roleId);
    /**
     * 获取shiro的认证信息
     */
    SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName);
}
guns-admin/src/main/java/com/stylefeng/guns/core/shiro/factory/ShiroFactroy.java
New file
@@ -0,0 +1,98 @@
package com.stylefeng.guns.core.shiro.factory;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.constant.state.ManagerStatus;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.SpringContextHolder;
import com.stylefeng.guns.modular.system.dao.MenuMapper;
import com.stylefeng.guns.modular.system.dao.UserMapper;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
@DependsOn("springContextHolder")
@Transactional(readOnly = true)
public class ShiroFactroy implements IShiro {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private MenuMapper menuMapper;
    public static IShiro me() {
        return SpringContextHolder.getBean(IShiro.class);
    }
    @Override
    public User user(String account) {
        User user = userMapper.getByAccount(account);
        // 账号不存在
        if (null == user) {
            throw new CredentialsException();
        }
        // 账号被冻结
        if (user.getStatus() != ManagerStatus.OK.getCode()) {
            throw new LockedAccountException();
        }
        return user;
    }
    @Override
    public ShiroUser shiroUser(User user) {
        ShiroUser shiroUser = new ShiroUser();
        shiroUser.setId(user.getId());
        shiroUser.setAccount(user.getAccount());
        shiroUser.setDeptId(user.getDeptid());
        shiroUser.setDeptName(ConstantFactory.me().getDeptName(user.getDeptid()));
        shiroUser.setName(user.getName());
        Integer[] roleArray = Convert.toIntArray(user.getRoleid());
        List<Integer> roleList = new ArrayList<Integer>();
        List<String> roleNameList = new ArrayList<String>();
        for (int roleId : roleArray) {
            roleList.add(roleId);
            roleNameList.add(ConstantFactory.me().getSingleRoleName(roleId));
        }
        shiroUser.setRoleList(roleList);
        shiroUser.setRoleNames(roleNameList);
        return shiroUser;
    }
    @Override
    public List<String> findPermissionsByRoleId(Integer roleId) {
        return menuMapper.getResUrlsByRoleId(roleId);
    }
    @Override
    public String findRoleNameByRoleId(Integer roleId) {
        return ConstantFactory.me().getSingleRoleTip(roleId);
    }
    @Override
    public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName) {
        String credentials = user.getPassword();
        // 密码加盐处理
        String source = user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(source);
        return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, realmName);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/tag/DictSelectorTag.java
New file
@@ -0,0 +1,201 @@
package com.stylefeng.guns.core.tag;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Dict;
import com.stylefeng.guns.modular.system.service.IDictService;
import org.beetl.core.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
 * 字典标签渲染
 *
 * @author zhangjiajia
 * @Date 2018年6月4日17:33:32
 */
@Component
@Scope("prototype")
public class DictSelectorTag extends Tag {
    @Autowired
    IDictService iDictService;
    @Override
    public void render(){
        //String tagName = (String) this.args[0];
        Map attrs = (Map) args[1];
        if(ToolUtil.isEmpty(attrs.get("code"))){
            throw new GunsException(BizExceptionEnum.ERROR_CODE_EMPTY);
        }
        //字典类型编码
        String code = attrs.get("code").toString();
        //控件显示类型select 选择框,radio 单选按钮,checkbox 多选按钮
        String type = ToolUtil.isNotEmpty(attrs.get("type"))?attrs.get("type").toString():"select";
        //开启多选
        String multiple = ToolUtil.isNotEmpty(attrs.get("multiple"))?attrs.get("multiple").toString():"";
        //字典名称
        String label = ToolUtil.isNotEmpty(attrs.get("label"))?attrs.get("label").toString():"";
        //提示
        String placeholder = (ToolUtil.isNotEmpty(attrs.get("placeholder"))?attrs.get("placeholder").toString():"");
        //宽度
        String width = ToolUtil.isNotEmpty(attrs.get("width"))?attrs.get("width").toString():"248";
        //默认值
        String value = ToolUtil.isNotEmpty(attrs.get("value"))?attrs.get("value").toString():"";
        //id
        String id = ToolUtil.isNotEmpty(attrs.get("id"))?attrs.get("id").toString():"";
        //name
        String name = ToolUtil.isNotEmpty(attrs.get("name"))?attrs.get("name").toString():"";
        //分割线
        String underline = ToolUtil.isNotEmpty(attrs.get("underline"))?attrs.get("underline").toString():"";
        //onchange事件
        String onchange = ToolUtil.isNotEmpty(attrs.get("onchange"))?attrs.get("onchange").toString():"";
        //readonly属性
        String readonly = ToolUtil.isNotEmpty(attrs.get("readonly"))?attrs.get("readonly").toString():"";
        //disabled属性
        String disabled = ToolUtil.isNotEmpty(attrs.get("disabled"))?attrs.get("disabled").toString():"";
        //searchnum 下拉选项数量达到多少启用搜索,默认10
        int searchnum = ToolUtil.isNum(attrs.get("searchnum"))?Integer.parseInt(attrs.get("searchnum").toString()):10;
        //根据code查询字典数据
        List<Dict>  list = iDictService.selectByParentCode(code);
        StringBuffer html = new StringBuffer();
        html.append("<div class=\"form-group\">\r\n");
        html.append("<label class=\"col-sm-3 control-label\">"+label+"</label>\r\n");
        html.append("<div class=\"col-sm-9\">\r\n");
        //单选按钮
        if("radio".equals(type)) {
            list.forEach(obj->{
                html.append("<label class=\"radio-inline i-checks\">\r\n<input type=\"radio\" ");
                //判断控件是否禁用
                if("true".equals(disabled)||"disabled".equals(disabled)) {
                    html.append("disabled ");
                }else{
                    if(ToolUtil.isNotEmpty(name)){
                        html.append("name=\""+name+"\" ");
                    }
                }
                if("true".equals(readonly)||"disabled".equals(readonly)) {
                    html.append("disabled ");
                }
                if(ToolUtil.isNotEmpty(value)&&value.equals(obj.getCode())){
                    html.append("checked ");
                }
                html.append("value=\""+obj.getCode()+"\" >"+obj.getName()+"</label>\r\n");
            });
        //多选按钮
        }else if("checkbox".equals(type)){
            list.forEach(obj->{
                html.append("<label class=\"checkbox-inline i-checks\">\r\n<input type=\"checkbox\" ");
                //判断控件是否禁用
                if("true".equals(disabled)||"disabled".equals(disabled)) {
                    html.append("disabled ");
                }else{
                    if(ToolUtil.isNotEmpty(name)){
                        html.append("name=\""+name+"\" ");
                    }
                }
                if("true".equals(readonly)||"disabled".equals(readonly)) {
                    html.append("disabled ");
                }
                if(ToolUtil.isNotEmpty(value)&&value.equals(obj.getCode())){
                    html.append("checked ");
                }
                html.append("value=\""+obj.getCode()+"\" >"+obj.getName()+"</label>\r\n");
            });
        //默认select
        }else{
            //开启多选
            if("true".equals(multiple)){
                if(list.size()>=searchnum) {
                    html.append("<select multiple ");
                }else{
                    html.append("<select multiple=\"multiple\" size=\"10\" ");
                }
            }else{
                html.append("<select ");
            }
            //判断控件是否启用提示
            if(ToolUtil.isNotEmpty(placeholder)){
                html.append(" data-placeholder=\""+placeholder+"\" ");
            }
            //判断控件是否禁用
            if("true".equals(disabled)||"disabled".equals(disabled)) {
                html.append("disabled=\"disabled\" ");
            }else{
                //启用
                if(ToolUtil.isNotEmpty(id)){
                    html.append("id=\""+id+"\" ");
                }
                if(ToolUtil.isNotEmpty(name)){
                    html.append("name=\""+name+"\" ");
                }
            }
            //判断是否启用搜索框
            //判断下拉数据,如果查询出来的条数达到启用搜索的数量就启用
            if(list.size()>=searchnum){
                html.append("class=\"form-control chosen-select\" style=\"width:"+width+"px\"  tabindex=\"1\" \r\n");
            } else{
                html.append("class=\"form-control\" style=\"width:"+width+"px\" \r\n");
            }
            //判断控件是否只读
            if("true".equals(readonly)||"readonly".equals(readonly)) {
                if(list.size()>=searchnum) {
                    html.append("disabled=\"disabled\" ");
                }else{
                    html.append("onfocus=\"this.defaultIndex=this.selectedIndex;\" onchange=\"this.selectedIndex=this.defaultIndex;\" ");
                }
            }
            //判断是否绑定onchange事件
            if(ToolUtil.isNotEmpty(onchange)){
                html.append("onchange=\""+onchange+"($(this).children('option:selected').val())\" ");
            }
            html.append(">");
            if(ToolUtil.isNotEmpty(placeholder)){
                html.append("<option value=\"\">"+placeholder+"</option>\r\n");
            }
            //将查询出来的数据添加到select中
            list.forEach(obj->{
                if(ToolUtil.isNotEmpty(value)&&value.equals(obj.getCode())){
                    html.append("<option selected value=\""+obj.getCode()+"\">"+obj.getName()+"</option>\r\n");
                }else{
                    html.append("<option value=\""+obj.getCode()+"\">"+obj.getName()+"</option>\r\n");
                }
            });
            html.append("</select>\r\n");
        }
        html.append("</div>\r\n</div>\r\n");
        //判断是否添加分割线
        if(ToolUtil.isNotEmpty(underline) && "true".equals(underline)) {
            html.append("<div class=\"hr-line-dashed\" ></div >\r\n");
        }
        try{
            this.ctx.byteWriter.writeString(html.toString());
        }catch (IOException e){
            throw new RuntimeException("输出字典标签错误");
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/util/ApiMenuFilter.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.config.properties.GunsProperties;
import com.stylefeng.guns.core.node.MenuNode;
import java.util.ArrayList;
import java.util.List;
/**
 * api接口文档显示过滤
 *
 * @author fengshuonan
 * @date 2017-08-17 16:55
 */
public class ApiMenuFilter extends MenuNode {
    public static List<MenuNode> build(List<MenuNode> nodes) {
        //如果关闭了接口文档,则不显示接口文档菜单
        GunsProperties gunsProperties = SpringContextHolder.getBean(GunsProperties.class);
        if (!gunsProperties.getSwaggerOpen()) {
            List<MenuNode> menuNodesCopy = new ArrayList<>();
            for (MenuNode menuNode : nodes) {
                if (Const.API_MENU_NAME.equals(menuNode.getName())) {
                    continue;
                } else {
                    menuNodesCopy.add(menuNode);
                }
            }
            nodes = menuNodesCopy;
        }
        return nodes;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/util/Contrast.java
New file
@@ -0,0 +1,211 @@
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.common.constant.dictmap.base.AbstractDictMap;
import com.stylefeng.guns.core.common.constant.dictmap.factory.DictFieldWarpperFactory;
import com.stylefeng.guns.core.support.StrKit;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;
/**
 * 对比两个对象的变化的工具类
 *
 * @author fengshuonan
 * @Date 2017/3/31 10:36
 */
public class Contrast {
    //记录每个修改字段的分隔符
    public static final String separator = ";;;";
    /**
     * 比较两个对象,并返回不一致的信息
     *
     * @author stylefeng
     * @Date 2017/5/9 19:34
     */
    public static String contrastObj(Object pojo1, Object pojo2) {
        String str = "";
        try {
            Class clazz = pojo1.getClass();
            Field[] fields = pojo1.getClass().getDeclaredFields();
            int i = 1;
            for (Field field : fields) {
                if ("serialVersionUID".equals(field.getName())) {
                    continue;
                }
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = pd.getReadMethod();
                Object o1 = getMethod.invoke(pojo1);
                Object o2 = getMethod.invoke(pojo2);
                if (o1 == null || o2 == null) {
                    continue;
                }
                if (o1 instanceof Date) {
                    o1 = DateUtil.getDay((Date) o1);
                }
                if (!o1.toString().equals(o2.toString())) {
                    if (i != 1) {
                        str += separator;
                    }
                    str += "字段名称" + field.getName() + ",旧值:" + o1 + ",新值:" + o2;
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }
    /**
     * 比较两个对象pojo1和pojo2,并输出不一致信息
     *
     * @author stylefeng
     * @Date 2017/5/9 19:34
     */
    public static String contrastObj(Class dictClass, String key, Object pojo1, Map<String, String> pojo2) throws IllegalAccessException, InstantiationException {
        AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
        String str = parseMutiKey(dictMap, key, pojo2) + separator;
        try {
            Class clazz = pojo1.getClass();
            Field[] fields = pojo1.getClass().getDeclaredFields();
            int i = 1;
            for (Field field : fields) {
                if ("serialVersionUID".equals(field.getName())) {
                    continue;
                }
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                Method getMethod = pd.getReadMethod();
                Object o1 = getMethod.invoke(pojo1);
                Object o2 = pojo2.get(StrKit.firstCharToLowerCase(getMethod.getName().substring(3)));
                if (o1 == null || o2 == null) {
                    continue;
                }
                if (o1 instanceof Date) {
                    o1 = DateUtil.getDay((Date) o1);
                } else if (o1 instanceof Integer) {
                    o2 = Integer.parseInt(o2.toString());
                }
                if (!o1.toString().equals(o2.toString())) {
                    if (i != 1) {
                        str += separator;
                    }
                    String fieldName = dictMap.get(field.getName());
                    String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(field.getName());
                    if (fieldWarpperMethodName != null) {
                        Object o1Warpper = DictFieldWarpperFactory.createFieldWarpper(o1, fieldWarpperMethodName);
                        Object o2Warpper = DictFieldWarpperFactory.createFieldWarpper(o2, fieldWarpperMethodName);
                        str += "字段名称:" + fieldName + ",旧值:" + o1Warpper + ",新值:" + o2Warpper;
                    } else {
                        str += "字段名称:" + fieldName + ",旧值:" + o1 + ",新值:" + o2;
                    }
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }
    /**
     * 比较两个对象pojo1和pojo2,并输出不一致信息
     *
     * @author stylefeng
     * @Date 2017/5/9 19:34
     */
    public static String contrastObjByName(Class dictClass, String key, Object pojo1, Map<String, String> pojo2) throws IllegalAccessException, InstantiationException {
        AbstractDictMap dictMap = (AbstractDictMap) dictClass.newInstance();
        String str = parseMutiKey(dictMap, key, pojo2) + separator;
        try {
            Class clazz = pojo1.getClass();
            Field[] fields = pojo1.getClass().getDeclaredFields();
            int i = 1;
            for (Field field : fields) {
                if ("serialVersionUID".equals(field.getName())) {
                    continue;
                }
                String prefix = "get";
                int prefixLength = 3;
                if (field.getType().getName().equals("java.lang.Boolean")) {
                    prefix = "is";
                    prefixLength = 2;
                }
                Method getMethod = null;
                try {
                    getMethod = clazz.getDeclaredMethod(prefix + StrKit.firstCharToUpperCase(field.getName()));
                } catch (java.lang.NoSuchMethodException e) {
                    System.out.println("this className:" + clazz.getName() + " is not methodName: " + e.getMessage());
                    continue;
                }
                Object o1 = getMethod.invoke(pojo1);
                Object o2 = pojo2.get(StrKit.firstCharToLowerCase(getMethod.getName().substring(prefixLength)));
                if (o1 == null || o2 == null) {
                    continue;
                }
                if (o1 instanceof Date) {
                    o1 = DateUtil.getDay((Date) o1);
                } else if (o1 instanceof Integer) {
                    o2 = Integer.parseInt(o2.toString());
                }
                if (!o1.toString().equals(o2.toString())) {
                    if (i != 1) {
                        str += separator;
                    }
                    String fieldName = dictMap.get(field.getName());
                    String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(field.getName());
                    if (fieldWarpperMethodName != null) {
                        Object o1Warpper = DictFieldWarpperFactory.createFieldWarpper(o1, fieldWarpperMethodName);
                        Object o2Warpper = DictFieldWarpperFactory.createFieldWarpper(o2, fieldWarpperMethodName);
                        str += "字段名称:" + fieldName + ",旧值:" + o1Warpper + ",新值:" + o2Warpper;
                    } else {
                        str += "字段名称:" + fieldName + ",旧值:" + o1 + ",新值:" + o2;
                    }
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str;
    }
    /**
     * 解析多个key(逗号隔开的)
     *
     * @author stylefeng
     * @Date 2017/5/16 22:19
     */
    public static String parseMutiKey(AbstractDictMap dictMap, String key, Map<String, String> requests) {
        StringBuilder sb = new StringBuilder();
        if (key.indexOf(",") != -1) {
            String[] keys = key.split(",");
            for (String item : keys) {
                String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(item);
                String value = requests.get(item);
                if (fieldWarpperMethodName != null) {
                    Object valueWarpper = DictFieldWarpperFactory.createFieldWarpper(value, fieldWarpperMethodName);
                    sb.append(dictMap.get(item) + "=" + valueWarpper + ",");
                } else {
                    sb.append(dictMap.get(item) + "=" + value + ",");
                }
            }
            return StrKit.removeSuffix(sb.toString(), ",");
        } else {
            String fieldWarpperMethodName = dictMap.getFieldWarpperMethodName(key);
            String value = requests.get(key);
            if (fieldWarpperMethodName != null) {
                Object valueWarpper = DictFieldWarpperFactory.createFieldWarpper(value, fieldWarpperMethodName);
                sb.append(dictMap.get(key) + "=" + valueWarpper);
            } else {
                sb.append(dictMap.get(key) + "=" + value);
            }
            return sb.toString();
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/util/JwtTokenUtil.java
New file
@@ -0,0 +1,127 @@
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.core.common.constant.JwtConstants;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
 * <p>jwt token工具类</p>
 * <pre>
 *     jwt的claim里一般包含以下几种数据:
 *         1. iss -- token的发行者
 *         2. sub -- 该JWT所面向的用户
 *         3. aud -- 接收该JWT的一方
 *         4. exp -- token的失效时间
 *         5. nbf -- 在此时间段之前,不会被处理
 *         6. iat -- jwt发布时间
 *         7. jti -- jwt唯一标识,防止重复使用
 * </pre>
 *
 * @author fengshuonan
 * @Date 2017/8/25 10:59
 */
@Component
public class JwtTokenUtil {
    /**
     * 获取用户名从token中
     */
    public static String getUsernameFromToken(String token) {
        return getClaimFromToken(token).getSubject();
    }
    /**
     * 获取jwt发布时间
     */
    public static Date getIssuedAtDateFromToken(String token) {
        return getClaimFromToken(token).getIssuedAt();
    }
    /**
     * 获取jwt失效时间
     */
    public static Date getExpirationDateFromToken(String token) {
        return getClaimFromToken(token).getExpiration();
    }
    /**
     * 获取jwt接收者
     */
    public static String getAudienceFromToken(String token) {
        return getClaimFromToken(token).getAudience();
    }
    /**
     * 获取私有的jwt claim
     */
    public static String getPrivateClaimFromToken(String token, String key) {
        return getClaimFromToken(token).get(key).toString();
    }
    /**
     * 获取jwt的payload部分
     */
    public static Claims getClaimFromToken(String token) {
        return Jwts.parser()
                .setSigningKey(JwtConstants.SECRET)
                .parseClaimsJws(token)
                .getBody();
    }
    /**
     * 解析token是否正确,不正确会报异常<br>
     */
    public static void parseToken(String token) throws JwtException {
        Jwts.parser().setSigningKey(JwtConstants.SECRET).parseClaimsJws(token).getBody();
    }
    /**
     * <pre>
     *  验证token是否失效
     *  true:过期   false:没过期
     * </pre>
     */
    public static Boolean isTokenExpired(String token) {
        try {
            final Date expiration = getExpirationDateFromToken(token);
            return expiration.before(new Date());
        } catch (ExpiredJwtException expiredJwtException) {
            return true;
        }
    }
    /**
     * 生成token(通过用户名和签名时候用的随机数)
     */
    public static String generateToken(String userId) {
        Map<String, Object> claims = new HashMap<>();
        return doGenerateToken(claims, userId);
    }
    /**
     * 生成token
     */
    private static String doGenerateToken(Map<String, Object> claims, String subject) {
        final Date createdDate = new Date();
        final Date expirationDate = new Date(createdDate.getTime() + JwtConstants.EXPIRATION * 1000);
        return Jwts.builder()
                .setClaims(claims)
                .setSubject(subject)
                .setIssuedAt(createdDate)
                .setExpiration(expirationDate)
                .signWith(SignatureAlgorithm.HS512, JwtConstants.SECRET)
                .compact();
    }
    /**
     * 获取混淆MD5签名用的随机字符串
     */
    public static String getRandomKey() {
        return ToolUtil.getRandomString(6);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/core/util/KaptchaUtil.java
New file
@@ -0,0 +1,16 @@
package com.stylefeng.guns.core.util;
import com.stylefeng.guns.config.properties.GunsProperties;
/**
 * 验证码工具类
 */
public class KaptchaUtil {
    /**
     * 获取验证码开关
     */
    public static Boolean getKaptchaOnOff() {
        return SpringContextHolder.getBean(GunsProperties.class).getKaptchaOpen();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/ApiController.java
New file
@@ -0,0 +1,80 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.ErrorTip;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.util.JwtTokenUtil;
import com.stylefeng.guns.modular.system.dao.UserMapper;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
/**
 * 接口控制器提供
 *
 * @author stylefeng
 * @Date 2018/7/20 23:39
 */
@RestController
@RequestMapping("/gunsApi")
public class ApiController extends BaseController {
    @Autowired
    private UserMapper userMapper;
    /**
     * api登录接口,通过账号密码获取token
     */
    @RequestMapping("/auth")
    public Object auth(@RequestParam("username") String username,
                       @RequestParam("password") String password) {
        //封装请求账号密码为shiro可验证的token
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, password.toCharArray());
        //获取数据库中的账号密码,准备比对
        User user = userMapper.getByAccount(username);
        String credentials = user.getPassword();
        String salt = user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(salt);
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(
                new ShiroUser(), credentials, credentialsSalt, "");
        //校验用户账号密码
        HashedCredentialsMatcher md5CredentialsMatcher = new HashedCredentialsMatcher();
        md5CredentialsMatcher.setHashAlgorithmName(ShiroKit.hashAlgorithmName);
        md5CredentialsMatcher.setHashIterations(ShiroKit.hashIterations);
        boolean passwordTrueFlag = md5CredentialsMatcher.doCredentialsMatch(
                usernamePasswordToken, simpleAuthenticationInfo);
        if (passwordTrueFlag) {
            HashMap<String, Object> result = new HashMap<>();
            result.put("token", JwtTokenUtil.generateToken(String.valueOf(user.getId())));
            return result;
        } else {
            return new ErrorTip(500, "账号密码错误!");
        }
    }
    /**
     * 测试接口是否走鉴权
     */
    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public Object test() {
        return SUCCESS_TIP;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/AppUserController.java
New file
@@ -0,0 +1,50 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.RegisterAccountReq;
import com.stylefeng.guns.modular.system.warpper.res.AppletLoginRes;
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.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 11:07
 */
@RestController
@RequestMapping("")
public class AppUserController {
    @Autowired
    private IAppUserService appUserService;
    @ResponseBody
    @PostMapping("/base/appUser/appletLogin")
    @ApiOperation(value = "微信小程序登录", tags = {"登录注册"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "jscode", value = "微信jscode", required = true)
    })
    public ResultUtil<AppletLoginRes> appletLogin(String jscode){
        return appUserService.appletLogin(jscode);
    }
    @ResponseBody
    @PostMapping("/base/appUser/registerAccount")
    @ApiOperation(value = "小程序注册账户", tags = {"登录注册"})
    public ResultUtil<AppletLoginRes> registerAccount(RegisterAccountReq req){
        return appUserService.registerAccount(req);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/BannerController.java
New file
@@ -0,0 +1,40 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.service.IBannerService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.res.BannerRes;
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.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 16:42
 */
@RestController
@RequestMapping("")
public class BannerController {
    @Autowired
    private IBannerService bannerService;
    @ResponseBody
    @GetMapping("/base/banner/getBanners")
    @ApiOperation(value = "获取各种banner", tags = {"首页"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "position", value = "位置(1=首页,2=详情)", required = true)
    })
    public ResultUtil<List<BannerRes>> getBanners(Integer position){
        List<BannerRes> banners = bannerService.getBanners(position);
        return ResultUtil.success(banners);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/EncyclopedicKnowledgeController.java
New file
@@ -0,0 +1,78 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledge;
import com.stylefeng.guns.modular.system.model.SysDataType;
import com.stylefeng.guns.modular.system.service.IEncyclopedicKnowledgeService;
import com.stylefeng.guns.modular.system.service.ISysDataTypeService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeRes;
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 java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:19
 */
@RestController
@RequestMapping("")
public class EncyclopedicKnowledgeController {
    @Autowired
    private IEncyclopedicKnowledgeService encyclopedicKnowledgeService;
    @Autowired
    private ISysDataTypeService sysDataTypeService;
    @ResponseBody
    @GetMapping("/base/encyclopedicKnowledge/getEncyclopedicKnowledgeType")
    @ApiOperation(value = "获取类别", tags = {"知识百科"})
    public ResultUtil<List<SysDataType>> getEncyclopedicKnowledgeType(){
        List<SysDataType> sysDataType = sysDataTypeService.getSysDataType(1);
        return ResultUtil.success(sysDataType);
    }
    @ResponseBody
    @GetMapping("/base/encyclopedicKnowledge/getEncyclopedicKnowledgeList")
    @ApiOperation(value = "获取列表数据", tags = {"知识百科"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "typeId", value = "类别id", required = true),
    })
    public ResultUtil<List<EncyclopedicKnowledgeRes>> getEncyclopedicKnowledgeList(Integer typeId){
        List<EncyclopedicKnowledgeRes> encyclopedicKnowledgeList = encyclopedicKnowledgeService.getEncyclopedicKnowledgeList(typeId);
        return ResultUtil.success(encyclopedicKnowledgeList);
    }
    @ResponseBody
    @PostMapping("/base/encyclopedicKnowledge/getEncyclopedicKnowledgeInfo")
    @ApiOperation(value = "获取详情", tags = {"知识百科"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "数据id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = false, paramType = "header")
    })
    public ResultUtil<EncyclopedicKnowledgeInfoRes> getEncyclopedicKnowledgeInfo(Integer id){
        EncyclopedicKnowledgeInfoRes encyclopedicKnowledgeInfo = encyclopedicKnowledgeService.getEncyclopedicKnowledgeInfo(id);
        return ResultUtil.success(encyclopedicKnowledgeInfo);
    }
    @ResponseBody
    @PostMapping("/api/encyclopedicKnowledge/upvoteEncyclopedicKnowledge")
    @ApiOperation(value = "点赞/取消点赞", tags = {"知识百科"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "数据id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil upvoteEncyclopedicKnowledge(Integer id){
        return encyclopedicKnowledgeService.upvoteEncyclopedicKnowledge(id);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/HouseResourceController.java
New file
@@ -0,0 +1,131 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.model.HouseType;
import com.stylefeng.guns.modular.system.service.ICollectionHouseResourceService;
import com.stylefeng.guns.modular.system.service.IHouseResourceService;
import com.stylefeng.guns.modular.system.service.IHouseTypeService;
import com.stylefeng.guns.modular.system.service.IReportHouseResourceService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.ReportHouseResourceReq;
import com.stylefeng.guns.modular.system.warpper.req.SearchHouseResourceReq;
import com.stylefeng.guns.modular.system.warpper.res.*;
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 java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/8 15:10
 */
@RestController
@RequestMapping("")
public class HouseResourceController {
    @Autowired
    private IHouseResourceService houseResourceService;
    @Autowired
    private IHouseTypeService houseTypeService;
    @Autowired
    private ICollectionHouseResourceService collectionHouseResourceService;
    @Autowired
    private IReportHouseResourceService reportHouseResourceService;
    @ResponseBody
    @GetMapping("/base/houseResource/searchHouseResource")
    @ApiOperation(value = "获取房源列表", tags = {"首页", "地图房源"})
    public ResultUtil<SearchHouseResourceRes> searchHouseResource(SearchHouseResourceReq req){
        SearchHouseResourceRes searchHouseResource = houseResourceService.searchHouseResource(req);
        return ResultUtil.success(searchHouseResource);
    }
    @ResponseBody
    @GetMapping("/base/houseType/getHouseType")
    @ApiOperation(value = "获取房源类型", tags = {"首页"})
    public ResultUtil<List<HouseType>> getHouseType(){
        List<HouseType> houseTypes = houseTypeService.selectList(null);
        return ResultUtil.success(houseTypes);
    }
    @ResponseBody
    @GetMapping("/base/houseResource/getDistrictHouseResourceNumber")
    @ApiOperation(value = "获取行政区域房源数量", tags = {"地图房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userType", value = "2=个人,3=中介,4=公司盘", required = true),
            @ApiImplicitParam(name = "dataType", value = "1=租房,2=卖房", required = true)
    })
    public ResultUtil<List<DistrictHouseResourceNumberRes>> getDistrictHouseResourceNumber(Integer userType, Integer dataType){
        List<DistrictHouseResourceNumberRes> districtHouseResourceNumber = houseResourceService.getDistrictHouseResourceNumber(userType, dataType);
        return ResultUtil.success(districtHouseResourceNumber);
    }
    @ResponseBody
    @PostMapping("/base/houseResource/getHouseResourceInfo")
    @ApiOperation(value = "获取房源详情", tags = {"详情"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = false, paramType = "header")
    })
    public ResultUtil<HouseResourceInfoRes> getHouseResourceInfo(Integer id){
        HouseResourceInfoRes houseResourceInfo = houseResourceService.getHouseResourceInfo(id);
        return ResultUtil.success(houseResourceInfo);
    }
    @ResponseBody
    @PostMapping("/api/houseResource/collectionHouseResource")
    @ApiOperation(value = "收藏/取消收藏房源操作", tags = {"详情"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil collectionHouseResource(Integer id){
        return collectionHouseResourceService.collectionHouseResource(id);
    }
    @ResponseBody
    @GetMapping("/base/houseResource/getNearbyHouseResource")
    @ApiOperation(value = "获取房源详情中的附近房源", tags = {"详情"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
    })
    public ResultUtil<List<SearchHouseResourceListRes>> getNearbyHouseResource(Integer id){
        List<SearchHouseResourceListRes> nearbyHouseResource = houseResourceService.getNearbyHouseResource(id);
        return ResultUtil.success(nearbyHouseResource);
    }
    @ResponseBody
    @GetMapping("/base/houseResource/getContactInformation")
    @ApiOperation(value = "获取联系方式", tags = {"详情"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
    })
    public ResultUtil<ContactInformationRes> getContactInformation(Integer id){
        ContactInformationRes contactInformation = houseResourceService.getContactInformation(id);
        return ResultUtil.success(contactInformation);
    }
    @ResponseBody
    @PostMapping("/api/houseResource/addReportHouseResource")
    @ApiOperation(value = "添加房源举报", tags = {"详情"})
    public ResultUtil addReportHouseResource(ReportHouseResourceReq req){
        return reportHouseResourceService.addReportHouseResource(req);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/HousingDemandController.java
New file
@@ -0,0 +1,119 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.service.ICollectionHousingDemandService;
import com.stylefeng.guns.modular.system.service.IHousingDemandService;
import com.stylefeng.guns.modular.system.service.IReportHousingDemandService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.HousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.req.ReportHousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.req.SearchHousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.res.ContactInformationRes;
import com.stylefeng.guns.modular.system.warpper.res.HousingDemandInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandRes;
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 java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 17:00
 */
@RestController
@RequestMapping("")
public class HousingDemandController {
    @Autowired
    private IHousingDemandService housingDemandService;
    @Autowired
    private IReportHousingDemandService reportHousingDemandService;
    @Autowired
    private ICollectionHousingDemandService collectionHousingDemandService;
    @ResponseBody
    @PostMapping("/api/housingDemand/addHousingDemand")
    @ApiOperation(value = "添加房源", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil addHousingDemand(HousingDemandReq req){
        return housingDemandService.addHousingDemand(req);
    }
    @ResponseBody
    @GetMapping("/base/housingDemand/searchHousingDemand")
    @ApiOperation(value = "求房源列表", tags = {"求房源"})
    public ResultUtil<SearchHousingDemandRes> searchHousingDemand(SearchHousingDemandReq req){
        SearchHousingDemandRes searchHousingDemandRes = housingDemandService.searchHousingDemand(req);
        return ResultUtil.success(searchHousingDemandRes);
    }
    @ResponseBody
    @PostMapping("/api/housingDemand/housingDemandInfo")
    @ApiOperation(value = "获取求房源详情", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "数据id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = false, paramType = "header")
    })
    public ResultUtil<HousingDemandInfoRes> housingDemandInfo(Integer id){
        HousingDemandInfoRes housingDemandInfoRes = housingDemandService.housingDemandInfo(id);
        return ResultUtil.success(housingDemandInfoRes);
    }
    @ResponseBody
    @PostMapping("/api/housingDemand/addReportHousingDemand")
    @ApiOperation(value = "添加举报数据", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil addReportHousingDemand(ReportHousingDemandReq req){
        return reportHousingDemandService.addReportHousingDemand(req);
    }
    @ResponseBody
    @PostMapping("/api/housingDemand/collectionHousingDemand")
    @ApiOperation(value = "收藏/取消收藏房源操作", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil collectionHousingDemand(Integer id){
        return collectionHousingDemandService.collectionHousingDemand(id);
    }
    @ResponseBody
    @GetMapping("/base/housingDemand/getContactInformation")
    @ApiOperation(value = "获取联系方式", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "房源id", required = true),
    })
    public ResultUtil<ContactInformationRes> getContactInformation(Integer id){
        ContactInformationRes contactInformation = housingDemandService.getContactInformation(id);
        return ResultUtil.success(contactInformation);
    }
    @ResponseBody
    @PostMapping("/api/housingDemand/getSurplusPushNumber")
    @ApiOperation(value = "获取剩余发布数量", tags = {"求房源"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "Bearer eyJhbGciOiJIUzUxMiJ....", required = true, paramType = "header")
    })
    public ResultUtil<Integer> getSurplusPushNumber(){
        return housingDemandService.getSurplusPushNumber();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/api/RegionController.java
New file
@@ -0,0 +1,39 @@
package com.stylefeng.guns.modular.api;
import com.stylefeng.guns.modular.system.service.IRegionService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.res.DistrictRes;
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 java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 14:34
 */
@RestController
@RequestMapping("")
public class RegionController {
    @Autowired
    private IRegionService regionService;
    @ResponseBody
    @GetMapping("/base/region/getDistrict")
    @ApiOperation(value = "获取区域数据", tags = {"首页"})
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "上级数据id,没有传0", required = true)
    })
    public ResultUtil<List<DistrictRes>> getDistrict(Integer parentId){
        List<DistrictRes> district = regionService.getDistrict(parentId);
        return ResultUtil.success(district);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/code/controller/CodeController.java
New file
@@ -0,0 +1,61 @@
package com.stylefeng.guns.modular.code.controller;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.config.properties.DruidProperties;
import com.stylefeng.guns.generator.action.config.WebGeneratorConfig;
import com.stylefeng.guns.generator.action.model.GenQo;
import com.stylefeng.guns.modular.code.factory.DefaultTemplateFactory;
import com.stylefeng.guns.modular.code.service.TableService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
/**
 * 代码生成控制器
 *
 * @author fengshuonan
 * @Date 2017年11月30日16:39:19
 */
@Controller
@RequestMapping("/code")
public class CodeController extends BaseController {
    private static String PREFIX = "/code";
    @Autowired
    private TableService tableService;
    @Autowired
    private DruidProperties druidProperties;
    /**
     * 跳转到代码生成主页
     */
    @RequestMapping("")
    public String blackboard(Model model) {
        model.addAttribute("tables", tableService.getAllTables());
        model.addAttribute("params", DefaultTemplateFactory.getDefaultParams());
        model.addAttribute("templates", DefaultTemplateFactory.getDefaultTemplates());
        return PREFIX + "/code.html";
    }
    /**
     * 生成代码
     */
    @ApiOperation("生成代码")
    @RequestMapping(value = "/generate", method = RequestMethod.POST)
    @ResponseBody
    public Object generate(GenQo genQo) {
        genQo.setUrl(druidProperties.getUrl());
        genQo.setUserName(druidProperties.getUsername());
        genQo.setPassword(druidProperties.getPassword());
        WebGeneratorConfig webGeneratorConfig = new WebGeneratorConfig(genQo);
        webGeneratorConfig.doMpGeneration();
        webGeneratorConfig.doGunsGeneration();
        return SUCCESS_TIP;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/code/factory/DefaultTemplateFactory.java
New file
@@ -0,0 +1,61 @@
package com.stylefeng.guns.modular.code.factory;
import com.stylefeng.guns.GunsApplication;
import com.stylefeng.guns.core.CoreFlag;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.generator.action.model.GenQo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 模板种类构建器
 *
 * @author fengshuonan
 * @date 2017-12-04-下午2:59
 */
public class DefaultTemplateFactory {
    /**
     * 获取所有的模板种类
     */
    public static List<Map<String,Object>> getDefaultTemplates(){
        ArrayList<Map<String, Object>> templates = new ArrayList<>();
        templates.add(create("controllerSwitch","controller-控制器模板"));
        templates.add(create("entitySwitch","entity-实体模板"));
        templates.add(create("serviceSwitch","service-service模板"));
        templates.add(create("daoSwitch","dao-dao模板"));
        templates.add(create("indexPageSwitch","indexPage-首页模板"));
        templates.add(create("addPageSwitch","addPage-添加页面模板"));
        templates.add(create("editPageSwitch","editPage-编辑页面模板"));
        templates.add(create("jsSwitch","indexJs-主页js模板"));
        templates.add(create("infoJsSwitch","infoJs-详情页js模板"));
        templates.add(create("sqlSwitch","sql-sql语句模板"));
        return templates;
    }
    /**
     * 获取默认的参数
     */
    public static GenQo getDefaultParams(){
        GenQo genQo = new GenQo();
        genQo.setProjectPath(ToolUtil.getWebRootPath(null));
        genQo.setAuthor("stylefeng");
        genQo.setProjectPackage(GunsApplication.class.getPackage().getName());
        genQo.setCorePackage(CoreFlag.class.getPackage().getName());
        genQo.setIgnoreTabelPrefix("sys_");
        genQo.setModuleName("system");
        genQo.setParentMenuName("系统管理");
        return genQo;
    }
    private static Map<String,Object> create(String key,String desc){
        HashMap<String, Object> template = new HashMap<>();
        template.put("key",key);
        template.put("desc",desc);
        return template;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/code/service/TableService.java
New file
@@ -0,0 +1,29 @@
package com.stylefeng.guns.modular.code.service;
import com.baomidou.mybatisplus.mapper.SqlRunner;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * 获取数据库所有的表
 *
 * @author fengshuonan
 * @date 2017-12-04-下午1:37
 */
@Service
public class TableService {
    @Value("${spring.datasource.db-name}")
    private String dbName;
    /**
     * 获取当前数据库所有的表信息
     */
    public List<Map<String, Object>> getAllTables() {
        String sql = "select TABLE_NAME as tableName,TABLE_COMMENT as tableComment from information_schema.`TABLES` where TABLE_SCHEMA = '" + dbName + "'";
        return SqlRunner.db().selectList(sql);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/DeptController.java
New file
@@ -0,0 +1,172 @@
package com.stylefeng.guns.modular.system.controller;
import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.annotion.Permission;
import com.stylefeng.guns.core.common.constant.dictmap.DeptDict;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Dept;
import com.stylefeng.guns.modular.system.service.IDeptService;
import com.stylefeng.guns.modular.system.warpper.DeptWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
/**
 * 部门控制器
 *
 * @author fengshuonan
 * @Date 2017年2月17日20:27:22
 */
@Controller
@RequestMapping("/dept")
public class DeptController extends BaseController {
    private String PREFIX = "/system/dept/";
    @Autowired
    private IDeptService deptService;
    /**
     * 跳转到部门管理首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "dept.html";
    }
    /**
     * 跳转到添加部门
     */
    @RequestMapping("/dept_add")
    public String deptAdd() {
        return PREFIX + "dept_add.html";
    }
    /**
     * 跳转到修改部门
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/dept_update/{deptId}")
    public String deptUpdate(@PathVariable Integer deptId, Model model) {
        Dept dept = deptService.selectById(deptId);
        model.addAttribute(dept);
        model.addAttribute("pName", ConstantFactory.me().getDeptName(dept.getPid()));
        LogObjectHolder.me().set(dept);
        return PREFIX + "dept_edit.html";
    }
    /**
     * 获取部门的tree列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/tree")
    @ResponseBody
    public List<ZTreeNode> tree() {
        List<ZTreeNode> tree = this.deptService.tree();
        tree.add(ZTreeNode.createParent());
        return tree;
    }
    /**
     * 新增部门
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "添加部门", key = "simplename", dict = DeptDict.class)
    @RequestMapping(value = "/add")
    @ResponseBody
    public Object add(Dept dept) {
        if (ToolUtil.isOneEmpty(dept, dept.getSimplename())) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //完善pids,根据pid拿到pid的pids
        deptSetPids(dept);
        this.deptService.insert(dept);
        return SUCCESS_TIP;
    }
    /**
     * 获取所有部门列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.deptService.list(condition);
        return super.warpObject(new DeptWarpper(list));
    }
    /**
     * 部门详情
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/detail/{deptId}")
    @ResponseBody
    public Object detail(@PathVariable("deptId") Integer deptId) {
        return deptService.selectById(deptId);
    }
    /**
     * 修改部门
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "修改部门", key = "simplename", dict = DeptDict.class)
    @RequestMapping(value = "/update")
    @ResponseBody
    public Object update(Dept dept) {
        if (ToolUtil.isEmpty(dept) || dept.getId() == null) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        deptSetPids(dept);
        Dept dept1 = deptService.selectById(dept.getId());
        deptService.updateById(dept);
        return SUCCESS_TIP;
    }
    /**
     * 删除部门
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "删除部门", key = "deptId", dict = DeptDict.class)
    @RequestMapping(value = "/delete")
    @ResponseBody
    public Object delete(@RequestParam Integer deptId) {
        //缓存被删除的部门名称
        LogObjectHolder.me().set(ConstantFactory.me().getDeptName(deptId));
        Dept dept = deptService.selectById(deptId);
        deptService.deleteDept(deptId);
        return SUCCESS_TIP;
    }
    private void deptSetPids(Dept dept) {
        if (ToolUtil.isEmpty(dept.getPid()) || dept.getPid().equals(0)) {
            dept.setPid(0);
            dept.setPids("[0],");
        } else {
            int pid = dept.getPid();
            Dept temp = deptService.selectById(pid);
            String pids = temp.getPids();
            dept.setPid(pid);
            dept.setPids(pids + "[" + pid + "],");
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/DictController.java
New file
@@ -0,0 +1,143 @@
package com.stylefeng.guns.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.annotion.Permission;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.dictmap.DictMap;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Dict;
import com.stylefeng.guns.modular.system.service.IDictService;
import com.stylefeng.guns.modular.system.warpper.DictWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
/**
 * 字典控制器
 *
 * @author fengshuonan
 * @Date 2017年4月26日 12:55:31
 */
@Controller
@RequestMapping("/dict")
public class DictController extends BaseController {
    private String PREFIX = "/system/dict/";
    @Autowired
    private IDictService dictService;
    /**
     * 跳转到字典管理首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "dict.html";
    }
    /**
     * 跳转到添加字典
     */
    @RequestMapping("/dict_add")
    public String deptAdd() {
        return PREFIX + "dict_add.html";
    }
    /**
     * 跳转到修改字典
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/dict_edit/{dictId}")
    public String deptUpdate(@PathVariable Integer dictId, Model model) {
        Dict dict = dictService.selectById(dictId);
        model.addAttribute("dict", dict);
        List<Dict> subDicts = dictService.selectList(new EntityWrapper<Dict>().eq("pid", dictId));
        model.addAttribute("subDicts", subDicts);
        LogObjectHolder.me().set(dict);
        return PREFIX + "dict_edit.html";
    }
    /**
     * 新增字典
     *
     * @param dictValues 格式例如   "1:启用;2:禁用;3:冻结"
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "添加字典记录", key = "dictName,dictValues", dict = DictMap.class)
    @RequestMapping(value = "/add")
    @ResponseBody
    public Object add(String dictCode,String dictTips,String dictName, String dictValues) {
        if (ToolUtil.isOneEmpty(dictCode,dictName, dictValues)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.dictService.addDict(dictCode,dictName,dictTips,dictValues);
        return SUCCESS_TIP;
    }
    /**
     * 获取所有字典列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.dictService.list(condition);
        return super.warpObject(new DictWarpper(list));
    }
    /**
     * 字典详情
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/detail/{dictId}")
    @ResponseBody
    public Object detail(@PathVariable("dictId") Integer dictId) {
        return dictService.selectById(dictId);
    }
    /**
     * 修改字典
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "修改字典", key = "dictName,dictValues", dict = DictMap.class)
    @RequestMapping(value = "/update")
    @ResponseBody
    public Object update(Integer dictId,String dictCode,String dictName, String dictTips,String dictValues) {
        if (ToolUtil.isOneEmpty(dictId, dictCode, dictName, dictValues)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        dictService.editDict(dictId, dictCode,dictName, dictTips,dictValues);
        return SUCCESS_TIP;
    }
    /**
     * 删除字典记录
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog(value = "删除字典记录", key = "dictId", dict = DictMap.class)
    @RequestMapping(value = "/delete")
    @ResponseBody
    public Object delete(@RequestParam Integer dictId) {
        //缓存被删除的名称
        LogObjectHolder.me().set(ConstantFactory.me().getDictName(dictId));
        this.dictService.delteDict(dictId);
        return SUCCESS_TIP;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/KaptchaController.java
New file
@@ -0,0 +1,140 @@
package com.stylefeng.guns.modular.system.controller;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.stylefeng.guns.config.properties.GunsProperties;
import com.stylefeng.guns.core.util.FileUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Properties;
/**
 * 验证码生成
 *
 * @author fengshuonan
 * @date 2017-05-05 23:10
 */
@Controller
@RequestMapping("/kaptcha")
public class KaptchaController {
    @Autowired
    private GunsProperties gunsProperties;
    @Autowired
    private Producer producer;
    /**
     * 生成验证码
     */
    @RequestMapping("")
    public void index(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        // create the text for the image
        String capText = producer.createText();
        // store the text in the session
        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, capText);
        // create the image with the text
        Properties properties = new Properties();
        // 设置边框
        properties.setProperty("kaptcha.border", "no");
        // 设置颜色
        properties.setProperty("kaptcha.border.color", "105,179,90");
        // 设置字体颜色
        properties.setProperty("kaptcha.textproducer.font.color", "blue");
        // 设置宽度
        properties.setProperty("kaptcha.image.width", "125");
        // 高度
        properties.setProperty("kaptcha.image.height", "42");
        // 设置session.key
        properties.setProperty("kaptcha.session.key", "code");
        // 设置文本长度
        properties.setProperty("kaptcha.textproducer.char.length", "4");
        // 设置字体
        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
        //字体大小
        properties.setProperty("kaptcha.textproducer.font.size", "35");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        BufferedImage bi = defaultKaptcha.createImage(capText);
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // write the data out
        try {
            ImageIO.write(bi, "jpg", out);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            try {
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 返回图片
     *
     * @author stylefeng
     * @Date 2017/5/24 23:00
     */
    @RequestMapping("/{pictureId}")
    public void renderPicture(@PathVariable("pictureId") String pictureId, HttpServletResponse response) {
        String path = gunsProperties.getFileUploadPath() + pictureId;
        try {
            byte[] bytes = FileUtil.toByteArray(path);
            response.getOutputStream().write(bytes);
        } catch (Exception e) {
            //如果找不到图片就返回一个默认图片
            try {
                response.sendRedirect("/static/img/girl.gif");
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/LoginController.java
New file
@@ -0,0 +1,246 @@
package com.stylefeng.guns.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.code.kaptcha.Constants;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.common.exception.InvalidKaptchaException;
import com.stylefeng.guns.core.log.LogManager;
import com.stylefeng.guns.core.log.factory.LogTaskFactory;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.node.MenuNode;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.util.ApiMenuFilter;
import com.stylefeng.guns.core.util.KaptchaUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.service.IMenuService;
import com.stylefeng.guns.modular.system.service.IUserService;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.stylefeng.guns.core.support.HttpKit.getIp;
/**
 * 登录控制器
 *
 * @author fengshuonan
 * @Date 2017年1月10日 下午8:25:24
 */
@Controller
public class LoginController extends BaseController {
    @Autowired
    private IMenuService menuService;
    @Autowired
    private IUserService userService;
    private Map<String, Long> loginTime = new HashMap<>();
    private Map<String, Integer> loginFailures = new HashMap<>();
    /**
     * 跳转到主页
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String index(Model model) {
        //获取菜单列表
        List<Integer> roleList = ShiroKit.getUser().getRoleList();
        if (roleList == null || roleList.size() == 0) {
            ShiroKit.getSubject().logout();
            model.addAttribute("tips", "该用户没有角色,无法登录");
            return "/login.html";
        }
        List<MenuNode> menus = menuService.getMenusByRoleIds(roleList);
        List<MenuNode> titles = MenuNode.buildTitle(menus);
        titles = ApiMenuFilter.build(titles);
        model.addAttribute("titles", titles);
        //获取用户头像
        Integer id = ShiroKit.getUser().getId();
        User user = userService.selectById(id);
        String avatar = user.getAvatar();
        model.addAttribute("avatar", avatar);
        return "/index.html";
    }
    /**
     * 跳转到登录页面
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model) {
        model.addAttribute("updatePaw", false);
        if (ShiroKit.isAuthenticated() || ShiroKit.getUser() != null) {
            return REDIRECT + "/";
        } else {
            return "/login.html";
        }
    }
    /**
     * 点击登录执行的动作
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String loginVali(Model model) {
        model.addAttribute("updatePaw", false);
        String username = super.getPara("username").trim();
        String password = super.getPara("password").trim();
        //验证验证码是否正确
        if (KaptchaUtil.getKaptchaOnOff()) {
            String kaptcha = super.getPara("kaptcha").trim();
            String code = (String) super.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
            if (ToolUtil.isEmpty(kaptcha) || !kaptcha.equalsIgnoreCase(code)) {
                model.addAttribute("tips", "验证码错误");
                return "/login.html";
            }
        }
        User user = userService.selectOne(new EntityWrapper<User>().eq("account", username).ne("status", 3));
        if(null == user){
            model.addAttribute("tips", "用户名或密码无效");
            return "/login.html";
        }
        if(2 == user.getStatus()){
            model.addAttribute("tips", "账户已被冻结,请联系管理员");
            return "/login.html";
        }
        if(null == user.getUpdatePasswordTime() || (user.getUpdatePasswordTime().getTime() + 7776000000L) <= System.currentTimeMillis()){
            model.addAttribute("tips", "密码已经90天没更新了,请先修改密码!");
            model.addAttribute("updatePaw", true);
            return "/login.html";
        }
        Long t = loginTime.get(username);
        t = null == t ? 0 : t;
        //超过30分钟初始化
        if(System.currentTimeMillis() - t > (30 * 60 * 1000)){
            loginFailures.put(username, 0);
            loginTime.put(username, System.currentTimeMillis());
        }
        Integer f = loginFailures.get(username);
        f = f == null ? 0 : f;
        //密码错误开始记录
        if(!user.getPassword().equals(ShiroKit.md5(password, user.getSalt()))){
            f++;
            loginFailures.put(username, f);
        }
        if(f > 5 && (System.currentTimeMillis() - t) <= (30 * 60 * 1000)){
            model.addAttribute("tips", "错误次数过多,请等30分钟再试!");
            return "/login.html";
        }
        if(!user.getPassword().equals(ShiroKit.md5(password, user.getSalt()))){
            model.addAttribute("tips", "账号密码错误");
            return "/login.html";
        }
        Subject currentUser = ShiroKit.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray());
        token.setRememberMe(false);
        currentUser.login(token);
        ShiroUser shiroUser = ShiroKit.getUser();
        super.getSession().setAttribute("shiroUser", shiroUser);
        super.getSession().setAttribute("username", shiroUser.getAccount());
        LogManager.me().executeLog(LogTaskFactory.loginLog(shiroUser.getId(), getIp()));
        ShiroKit.getSession().setAttribute("sessionFlag", true);
        return REDIRECT + "/";
    }
    /**
     * 退出登录
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logOut() {
        LogManager.me().executeLog(LogTaskFactory.exitLog(ShiroKit.getUser().getId(), getIp()));
        ShiroKit.getSubject().logout();
        deleteAllCookie();
        return REDIRECT + "/login";
    }
    /**
     * 跳转到面修改页
     * @return
     */
    @RequestMapping(value = "/updatepwdpage", method = RequestMethod.GET)
    public String updatepwdpage(){
        return "/updatePass.html";
    }
    /**
     * 修改密码
     * @param model
     * @return
     */
    @RequestMapping(value = "/updatepwd", method = RequestMethod.POST)
    public String updatepwd(Model model){
        String username = super.getPara("username").trim();
        String oldPassword = super.getPara("oldPassword").trim();
        String newPassword = super.getPara("newPassword").trim();
        String rePassword = super.getPara("rePassword");
        if(ToolUtil.isEmpty(username)){
            model.addAttribute("tips", "用户名不能为空");
            return "/updatePass.html";
        }
        if(ToolUtil.isEmpty(oldPassword)){
            model.addAttribute("tips", "原始密码不能为空");
            return "/updatePass.html";
        }
        if(ToolUtil.isEmpty(newPassword)){
            model.addAttribute("tips", "新密码不能为空");
            return "/updatePass.html";
        }
        if(ToolUtil.isEmpty(rePassword)){
            model.addAttribute("tips", "确认密码不能为空");
            return "/updatePass.html";
        }
        if(!newPassword.equals(rePassword)){
            model.addAttribute("tips", "两次密码不一致");
            return "/updatePass.html";
        }
        User user = userService.selectOne(new EntityWrapper<User>().eq("account", username).ne("status", 3));
        if(null == user){
            model.addAttribute("tips", "用户名或密码无效");
            return "/updatePass.html";
        }
        if(2 == user.getStatus()){
            model.addAttribute("tips", "账户已被冻结,请联系管理员");
            return "/updatePass.html";
        }
        if(!user.getPassword().equals(ShiroKit.md5(oldPassword, user.getSalt()))){
            model.addAttribute("tips", "用户名或密码无效");
            return "/updatePass.html";
        }
        user.setPassword(ShiroKit.md5(newPassword, user.getSalt()));
        user.setUpdatePasswordTime(new Date());
        userService.updateById(user);
        return REDIRECT + "/login";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/LoginLogController.java
New file
@@ -0,0 +1,70 @@
package com.stylefeng.guns.modular.system.controller;
import com.baomidou.mybatisplus.mapper.SqlRunner;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.annotion.Permission;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.factory.PageFactory;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.modular.system.model.LoginLog;
import com.stylefeng.guns.modular.system.service.ILoginLogService;
import com.stylefeng.guns.modular.system.warpper.LogWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
import java.util.Map;
/**
 * 日志管理的控制器
 *
 * @author fengshuonan
 * @Date 2017年4月5日 19:45:36
 */
@Controller
@RequestMapping("/loginLog")
public class LoginLogController extends BaseController {
    private static String PREFIX = "/system/log/";
    @Autowired
    private ILoginLogService loginLogService;
    /**
     * 跳转到日志管理的首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "login_log.html";
    }
    /**
     * 查询登录日志列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String beginTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String logName) {
        Page<LoginLog> page = new PageFactory<LoginLog>().defaultPage();
        List<Map<String, Object>> result = loginLogService.getLoginLogs(page, beginTime, endTime, logName, page.getOrderByField(), page.isAsc());
        page.setRecords((List<LoginLog>) new LogWarpper(result).warp());
        return super.packForBT(page);
    }
    /**
     * 清空日志
     */
    @DataSource(name = "dataSourceGuns")
    @BussinessLog("清空登录日志")
    @RequestMapping("/delLoginLog")
    @ResponseBody
    public Object delLog() {
        SqlRunner.db().delete("delete from sys_login_log");
        return SUCCESS_TIP;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/MenuController.java
New file
@@ -0,0 +1,249 @@
package com.stylefeng.guns.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.Tip;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.annotion.Permission;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.dictmap.MenuDict;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.constant.state.MenuStatus;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.core.support.BeanKit;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Menu;
import com.stylefeng.guns.modular.system.service.IMenuService;
import com.stylefeng.guns.modular.system.warpper.MenuWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
 * 菜单控制器
 *
 * @author fengshuonan
 * @Date 2017年2月12日21:59:14
 */
@Controller
@RequestMapping("/menu")
public class MenuController extends BaseController {
    private static String PREFIX = "/system/menu/";
    @Autowired
    private IMenuService menuService;
    /**
     * 跳转到菜单列表列表页面
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "menu.html";
    }
    /**
     * 跳转到菜单列表列表页面
     */
    @RequestMapping(value = "/menu_add")
    public String menuAdd() {
        return PREFIX + "menu_add.html";
    }
    /**
     * 跳转到菜单详情列表页面
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/menu_edit/{menuId}")
    public String menuEdit(@PathVariable Long menuId, Model model) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        Menu menu = this.menuService.selectById(menuId);
        //获取父级菜单的id
        Menu temp = new Menu();
        temp.setCode(menu.getPcode());
        Menu pMenu = this.menuService.selectOne(new EntityWrapper<>(temp));
        //如果父级是顶级菜单
        if (pMenu == null) {
            menu.setPcode("0");
        } else {
            //设置父级菜单的code为父级菜单的id
            menu.setPcode(String.valueOf(pMenu.getId()));
        }
        Map<String, Object> menuMap = BeanKit.beanToMap(menu);
        menuMap.put("pcodeName", ConstantFactory.me().getMenuNameByCode(temp.getCode()));
        model.addAttribute("menu", menuMap);
        LogObjectHolder.me().set(menu);
        return PREFIX + "menu_edit.html";
    }
    /**
     * 修该菜单
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/edit")
    @BussinessLog(value = "修改菜单", key = "name", dict = MenuDict.class)
    @ResponseBody
    public Tip edit(@Valid Menu menu, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //设置父级菜单编号
        menuSetPcode(menu);
        this.menuService.updateById(menu);
        return SUCCESS_TIP;
    }
    /**
     * 获取菜单列表
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String menuName, @RequestParam(required = false) String level) {
        List<Map<String, Object>> menus = this.menuService.selectMenus(menuName, level);
        return super.warpObject(new MenuWarpper(menus));
    }
    /**
     * 新增菜单
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/add")
    @BussinessLog(value = "菜单新增", key = "name", dict = MenuDict.class)
    @ResponseBody
    public Tip add(@Valid Menu menu, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //判断是否存在该编号
        String existedMenuName = ConstantFactory.me().getMenuNameByCode(menu.getCode());
        if (ToolUtil.isNotEmpty(existedMenuName)) {
            throw new GunsException(BizExceptionEnum.EXISTED_THE_MENU);
        }
        //设置父级菜单编号
        menuSetPcode(menu);
        menu.setStatus(MenuStatus.ENABLE.getCode());
        this.menuService.insert(menu);
        return SUCCESS_TIP;
    }
    /**
     * 删除菜单
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/remove")
    @BussinessLog(value = "删除菜单", key = "menuId", dict = MenuDict.class)
    @ResponseBody
    public Tip remove(@RequestParam Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //缓存菜单的名称
        LogObjectHolder.me().set(ConstantFactory.me().getMenuName(menuId));
        this.menuService.delMenuContainSubMenus(menuId);
        return SUCCESS_TIP;
    }
    /**
     * 查看菜单
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/view/{menuId}")
    @ResponseBody
    public Tip view(@PathVariable Long menuId) {
        if (ToolUtil.isEmpty(menuId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.menuService.selectById(menuId);
        return SUCCESS_TIP;
    }
    /**
     * 获取菜单列表(首页用)
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/menuTreeList")
    @ResponseBody
    public List<ZTreeNode> menuTreeList() {
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList();
        return roleTreeList;
    }
    /**
     * 获取菜单列表(选择父级菜单用)
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/selectMenuTreeList")
    @ResponseBody
    public List<ZTreeNode> selectMenuTreeList() {
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList();
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
    /**
     * 获取角色列表
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/menuTreeListByRoleId/{roleId}")
    @ResponseBody
    public List<ZTreeNode> menuTreeListByRoleId(@PathVariable Integer roleId) {
        List<Long> menuIds = this.menuService.getMenuIdsByRoleId(roleId);
        if (ToolUtil.isEmpty(menuIds)) {
            List<ZTreeNode> roleTreeList = this.menuService.menuTreeList();
            return roleTreeList;
        } else {
            List<ZTreeNode> roleTreeListByUserId = this.menuService.menuTreeListByMenuIds(menuIds);
            return roleTreeListByUserId;
        }
    }
    /**
     * 根据请求的父级菜单编号设置pcode和层级
     */
    private void menuSetPcode(@Valid Menu menu) {
        if (ToolUtil.isEmpty(menu.getPcode()) || menu.getPcode().equals("0")) {
            menu.setPcode("0");
            menu.setPcodes("[0],");
            menu.setLevels(1);
        } else {
            long code = Long.parseLong(menu.getPcode());
            Menu pMenu = menuService.selectById(code);
            Integer pLevels = pMenu.getLevels();
            menu.setPcode(pMenu.getCode());
            //如果编号和父编号一致会导致无限递归
            if (menu.getCode().equals(menu.getPcode())) {
                throw new GunsException(BizExceptionEnum.MENU_PCODE_COINCIDENCE);
            }
            menu.setLevels(pLevels + 1);
            menu.setPcodes(pMenu.getPcodes() + "[" + pMenu.getCode() + "],");
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/NoticeController.java
New file
@@ -0,0 +1,145 @@
package com.stylefeng.guns.modular.system.controller;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.constant.dictmap.NoticeMap;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Notice;
import com.stylefeng.guns.modular.system.service.INoticeService;
import com.stylefeng.guns.modular.system.warpper.NoticeWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Date;
import java.util.List;
import java.util.Map;
/**
 * 通知控制器
 *
 * @author fengshuonan
 * @Date 2017-05-09 23:02:21
 */
@Controller
@RequestMapping("/notice")
public class NoticeController extends BaseController {
    private String PREFIX = "/system/notice/";
    @Autowired
    private INoticeService noticeService;
    /**
     * 跳转到通知列表首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "notice.html";
    }
    /**
     * 跳转到添加通知
     */
    @RequestMapping("/notice_add")
    public String noticeAdd() {
        return PREFIX + "notice_add.html";
    }
    /**
     * 跳转到修改通知
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/notice_update/{noticeId}")
    public String noticeUpdate(@PathVariable Integer noticeId, Model model) {
        Notice notice = this.noticeService.selectById(noticeId);
        model.addAttribute("notice",notice);
        LogObjectHolder.me().set(notice);
        return PREFIX + "notice_edit.html";
    }
    /**
     * 跳转到首页通知
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/hello")
    public String hello() {
        List<Map<String, Object>> notices = noticeService.list(null);
        super.setAttr("noticeList",notices);
        return "/blackboard.html";
    }
    /**
     * 获取通知列表
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.noticeService.list(condition);
        return super.warpObject(new NoticeWrapper(list));
    }
    /**
     * 新增通知
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/add")
    @ResponseBody
    @BussinessLog(value = "新增通知",key = "title",dict = NoticeMap.class)
    public Object add(Notice notice) {
        if (ToolUtil.isOneEmpty(notice, notice.getTitle(), notice.getContent())) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        notice.setCreater(ShiroKit.getUser().getId());
        notice.setCreatetime(new Date());
        notice.insert();
        return SUCCESS_TIP;
    }
    /**
     * 删除通知
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/delete")
    @ResponseBody
    @BussinessLog(value = "删除通知",key = "noticeId",dict = NoticeMap.class)
    public Object delete(@RequestParam Integer noticeId) {
        //缓存通知名称
        LogObjectHolder.me().set(ConstantFactory.me().getNoticeTitle(noticeId));
        this.noticeService.deleteById(noticeId);
        return SUCCESS_TIP;
    }
    /**
     * 修改通知
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/update")
    @ResponseBody
    @BussinessLog(value = "修改通知",key = "title",dict = NoticeMap.class)
    public Object update(Notice notice) {
        if (ToolUtil.isOneEmpty(notice, notice.getId(), notice.getTitle(), notice.getContent())) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        Notice old = this.noticeService.selectById(notice.getId());
        old.setTitle(notice.getTitle());
        old.setContent(notice.getContent());
        old.updateById();
        return SUCCESS_TIP;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/RoleController.java
New file
@@ -0,0 +1,236 @@
package com.stylefeng.guns.modular.system.controller;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.Tip;
import com.stylefeng.guns.core.cache.CacheKit;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.cache.Cache;
import com.stylefeng.guns.core.common.constant.dictmap.RoleDict;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.Role;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.service.IRoleService;
import com.stylefeng.guns.modular.system.service.IUserService;
import com.stylefeng.guns.modular.system.warpper.RoleWarpper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.validation.Valid;
import java.util.List;
import java.util.Map;
/**
 * 角色控制器
 *
 * @author fengshuonan
 * @Date 2017年2月12日21:59:14
 */
@Controller
@RequestMapping("/role")
public class RoleController extends BaseController {
    private static String PREFIX = "/system/role";
    @Autowired
    private IUserService userService;
    @Autowired
    private IRoleService roleService;
    /**
     * 跳转到角色列表页面
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "/role.html";
    }
    /**
     * 跳转到添加角色
     */
    @RequestMapping(value = "/role_add")
    public String roleAdd() {
        return PREFIX + "/role_add.html";
    }
    /**
     * 跳转到修改角色
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/role_edit/{roleId}")
    public String roleEdit(@PathVariable Integer roleId, Model model) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        Role role = this.roleService.selectById(roleId);
        model.addAttribute(role);
        model.addAttribute("pName", ConstantFactory.me().getSingleRoleName(role.getPid()));
        model.addAttribute("deptName", ConstantFactory.me().getDeptName(role.getDeptid()));
        LogObjectHolder.me().set(role);
        return PREFIX + "/role_edit.html";
    }
    /**
     * 跳转到角色分配
     */
    @RequestMapping(value = "/role_assign/{roleId}")
    public String roleAssign(@PathVariable("roleId") Integer roleId, Model model) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        model.addAttribute("roleId", roleId);
        model.addAttribute("roleName", ConstantFactory.me().getSingleRoleName(roleId));
        return PREFIX + "/role_assign.html";
    }
    /**
     * 获取角色列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String roleName) {
        List<Map<String, Object>> roles = this.roleService.selectRoles(super.getPara("roleName"));
        return super.warpObject(new RoleWarpper(roles));
    }
    /**
     * 角色新增
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/add")
    @BussinessLog(value = "添加角色", key = "name", dict = RoleDict.class)
    @ResponseBody
    public Tip add(@Valid Role role, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        role.setId(null);
        this.roleService.insert(role);
        return SUCCESS_TIP;
    }
    /**
     * 角色修改
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/edit")
    @BussinessLog(value = "修改角色", key = "name", dict = RoleDict.class)
    @ResponseBody
    public Tip edit(@Valid Role role, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        Role role1 = roleService.selectById(role.getId());
        this.roleService.updateById(role);
        //删除缓存
        CacheKit.removeAll(Cache.CONSTANT);
        return SUCCESS_TIP;
    }
    /**
     * 删除角色
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping(value = "/remove")
    @BussinessLog(value = "删除角色", key = "roleId", dict = RoleDict.class)
    @ResponseBody
    public Tip remove(@RequestParam Integer roleId) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能删除超级管理员角色
        if (roleId.equals(Const.ADMIN_ROLE_ID)) {
            throw new GunsException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }
        //缓存被删除的角色名称
        LogObjectHolder.me().set(ConstantFactory.me().getSingleRoleName(roleId));
        Role role = roleService.selectById(roleId);
        this.roleService.delRoleById(roleId);
        //删除缓存
        CacheKit.removeAll(Cache.CONSTANT);
        return SUCCESS_TIP;
    }
    /**
     * 查看角色
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/view/{roleId}")
    @ResponseBody
    public Tip view(@PathVariable Integer roleId) {
        if (ToolUtil.isEmpty(roleId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.roleService.selectById(roleId);
        return SUCCESS_TIP;
    }
    /**
     * 配置权限
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/setAuthority")
    @BussinessLog(value = "配置权限", key = "roleId,ids", dict = RoleDict.class)
    @ResponseBody
    public Tip setAuthority(@RequestParam("roleId") Integer roleId, @RequestParam("ids") String ids) {
        if (ToolUtil.isOneEmpty(roleId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.roleService.setAuthority(roleId, ids);
        Role role = roleService.selectById(roleId);
        return SUCCESS_TIP;
    }
    /**
     * 获取角色列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/roleTreeList")
    @ResponseBody
    public List<ZTreeNode> roleTreeList() {
        List<ZTreeNode> roleTreeList = this.roleService.roleTreeList();
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
    /**
     * 获取角色列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping(value = "/roleTreeListByUserId/{userId}")
    @ResponseBody
    public List<ZTreeNode> roleTreeListByUserId(@PathVariable Integer userId) {
        User theUser = this.userService.selectById(userId);
        String roleid = theUser.getRoleid();
        if (ToolUtil.isEmpty(roleid)) {
            List<ZTreeNode> roleTreeList = this.roleService.roleTreeList();
            return roleTreeList;
        } else {
            String[] strArray = Convert.toStrArray(",", roleid);
            List<ZTreeNode> roleTreeListByUserId = this.roleService.roleTreeListByRoleId(strArray);
            return roleTreeListByUserId;
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/SysRegionController.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.modular.system.model.Region;
import com.stylefeng.guns.modular.system.service.IRegionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.List;
@Controller
@RequestMapping("/region")
public class SysRegionController {
    @Autowired
    private IRegionService regionService;
    /**
     * 获取市级数据列表
     */
    @RequestMapping(value = "/cityList")
    @ResponseBody
    public Object cityList(Integer parentId) {
        if(parentId==null){
            parentId=0;
        }
        List<Region> cities=regionService.selectList(new EntityWrapper<Region>().eq("parentId",parentId));
        return cities;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/UEditorController.java
New file
@@ -0,0 +1,111 @@
package com.stylefeng.guns.modular.system.controller;
import com.baidu.ueditor.ActionEnter;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
 * 百度富文本控制器
 */
@Controller
public class UEditorController {
    @RequestMapping("/config.json")
    public void ueditorConfig(HttpServletRequest request, HttpServletResponse response){
        String rootPath = ClassUtils.getDefaultClassLoader().getResource("").getPath() + "static/ueditor1_4_3_3/jsp";
        String property = System.getProperty("os.name");
        try {
            rootPath = URLDecoder.decode(rootPath, "UTF-8");
            if(property.indexOf("Windows") != -1){
                rootPath = rootPath.substring(1);
            }
            response.setContentType("application/json");
            PrintWriter out = response.getWriter();
            String exec = new ActionEnter(request, rootPath).exec();
//            StringBuilder builder = new StringBuilder();
//            InputStreamReader reader = new InputStreamReader(new FileInputStream(rootPath), "UTF-8");
//            BufferedReader bfReader = new BufferedReader(reader);
//            String tmpContent = null;
//            while((tmpContent = bfReader.readLine()) != null) {
//                builder.append(tmpContent);
//            }
//            bfReader.close();
//            String s = builder.toString().replaceAll("/\\*[\\s\\S]*?\\*/", "");
            out.write(exec);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    @RequestMapping("/ueditor/uploadFileData")
    @ResponseBody
    public Map<String,String> uploadFileData(@RequestParam("upfile") MultipartFile upfile, HttpServletRequest request) throws IOException {
        //文件原名称
        String fileName = upfile.getOriginalFilename();
        // 保存文件的新名字
        String nowName = fileName.substring(upfile.getOriginalFilename().lastIndexOf("."));
//        String s = uploadUtil.uploadFile(2, "file", upfile);
        String s = "";
        //返回结果信息(UEditor官方要求这个json格式)
        Map<String,String> map = new HashMap<String,String >();
        //是否上传成功
        map.put("state", "SUCCESS");
        //现在文件名称
        map.put("title", nowName);
        //文件原名称
        map.put("original", fileName);
        //文件类型 .+后缀名
        map.put("type", fileName.substring(upfile.getOriginalFilename().lastIndexOf(".")));
        //文件路径
        map.put("url", s);
        //文件大小(字节数)
        map.put("size", upfile.getSize()+"");
        return map;
    }
    @RequestMapping("/ueditor/uploadImageData")
    @ResponseBody
    public Map<String,String> uploadImage(@RequestParam("upfile") MultipartFile upfile, HttpServletRequest request) throws IOException {
        //文件原名称
        String fileName = upfile.getOriginalFilename();
        // 保存文件的新名字
        String nowName = UUID.randomUUID()+fileName.substring(upfile.getOriginalFilename().lastIndexOf("."));
//        String s = uploadUtil.uploadFile(1, "img", upfile);
        String s = "";
        //返回结果信息(UEditor官方要求这个json格式)
        Map<String,String> map = new HashMap<String,String >();
        //是否上传成功
        map.put("state", "SUCCESS");
        //现在文件名称
        map.put("title", nowName);
        //文件原名称
        map.put("original", fileName);
        //文件类型 .+后缀名
        map.put("type", fileName.substring(upfile.getOriginalFilename().lastIndexOf(".")));
        //文件路径
        map.put("url", s);
        //文件大小(字节数)
        map.put("size", upfile.getSize()+"");
        return map;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/controller/UserMgrController.java
New file
@@ -0,0 +1,395 @@
package com.stylefeng.guns.modular.system.controller;
import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.config.properties.GunsProperties;
import com.stylefeng.guns.core.base.controller.BaseController;
import com.stylefeng.guns.core.base.tips.Tip;
import com.stylefeng.guns.core.common.annotion.BussinessLog;
import com.stylefeng.guns.core.common.constant.Const;
import com.stylefeng.guns.core.common.constant.dictmap.UserDict;
import com.stylefeng.guns.core.common.constant.factory.ConstantFactory;
import com.stylefeng.guns.core.common.constant.state.ManagerStatus;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.db.Db;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.core.log.LogObjectHolder;
import com.stylefeng.guns.core.mutidatasource.annotion.DataSource;
import com.stylefeng.guns.core.shiro.ShiroKit;
import com.stylefeng.guns.core.shiro.ShiroUser;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.UserMapper;
import com.stylefeng.guns.modular.system.factory.UserFactory;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.service.IUserService;
import com.stylefeng.guns.modular.system.transfer.UserDto;
import com.stylefeng.guns.modular.system.warpper.UserWarpper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.naming.NoPermissionException;
import javax.validation.Valid;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * 系统管理员控制器
 *
 * @author fengshuonan
 * @Date 2017年1月11日 下午1:08:17
 */
@Controller
@RequestMapping("/mgr")
public class UserMgrController extends BaseController {
    private static String PREFIX = "/system/user/";
    @Autowired
    private GunsProperties gunsProperties;
    @Autowired
    private IUserService userService;
    /**
     * 跳转到查看管理员列表的页面
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "user.html";
    }
    /**
     * 跳转到查看管理员列表的页面
     */
    @RequestMapping("/user_add")
    public String addView() {
        return PREFIX + "user_add.html";
    }
    /**
     * 跳转到角色分配页面
     */
    //@RequiresPermissions("/mgr/role_assign")  //利用shiro自带的权限检查
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/role_assign/{userId}")
    public String roleAssign(@PathVariable Integer userId, Model model) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        User user = (User) Db.create(UserMapper.class).selectOneByCon("id", userId);
        model.addAttribute("userId", userId);
        model.addAttribute("userAccount", user.getAccount());
        return PREFIX + "user_roleassign.html";
    }
    /**
     * 跳转到编辑管理员页面
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/user_edit/{userId}")
    public String userEdit(@PathVariable Integer userId, Model model) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        User user = this.userService.selectById(userId);
        model.addAttribute(user);
        model.addAttribute("roleName", ConstantFactory.me().getRoleName(user.getRoleid()));
        model.addAttribute("deptName", ConstantFactory.me().getDeptName(user.getDeptid()));
        LogObjectHolder.me().set(user);
        return PREFIX + "user_edit.html";
    }
    /**
     * 跳转到查看用户详情页面
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/user_info")
    public String userInfo(Model model) {
        Integer userId = ShiroKit.getUser().getId();
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        User user = this.userService.selectById(userId);
        model.addAttribute(user);
        model.addAttribute("roleName", ConstantFactory.me().getRoleName(user.getRoleid()));
        model.addAttribute("deptName", ConstantFactory.me().getDeptName(user.getDeptid()));
        LogObjectHolder.me().set(user);
        return PREFIX + "user_view.html";
    }
    /**
     * 跳转到修改密码界面
     */
    @RequestMapping("/user_chpwd")
    public String chPwd() {
        return PREFIX + "user_chpwd.html";
    }
    /**
     * 修改当前用户的密码
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/changePwd")
    @ResponseBody
    public Object changePwd(@RequestParam String oldPwd, @RequestParam String newPwd, @RequestParam String rePwd) {
        if (!newPwd.equals(rePwd)) {
            throw new GunsException(BizExceptionEnum.TWO_PWD_NOT_MATCH);
        }
        Integer userId = ShiroKit.getUser().getId();
        User user = userService.selectById(userId);
        User user1 = new User();
        BeanUtils.copyProperties(user, user1);
        String oldMd5 = ShiroKit.md5(oldPwd, user.getSalt());
        if (user.getPassword().equals(oldMd5)) {
            String newMd5 = ShiroKit.md5(newPwd, user.getSalt());
            user.setPassword(newMd5);
            user.setUpdatePasswordTime(new Date());
            user.updateById();
            return SUCCESS_TIP;
        } else {
            throw new GunsException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
        }
    }
    /**
     * 查询管理员列表
     */
    @DataSource(name = "dataSourceBiz")
    @RequestMapping("/list")
    @ResponseBody
    public Object list(@RequestParam(required = false) String name, @RequestParam(required = false) String beginTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) Integer deptid) {
//        if (ShiroKit.isAdmin()) {
//            List<Map<String, Object>> users = userService.selectUsers(null, name, beginTime, endTime, deptid);
//            return new UserWarpper(users).warp();
//        } else {
//            DataScope dataScope = new DataScope(ShiroKit.getDeptDataScope());
//            List<Map<String, Object>> users = userService.selectUsers(dataScope, name, beginTime, endTime, deptid);
//            return new UserWarpper(users).warp();
//        }
        List<Map<String, Object>> users = userService.selectUsers(null, name, beginTime, endTime, deptid);
        return new UserWarpper(users).warp();
    }
    /**
     * 添加管理员
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/add")
    @BussinessLog(value = "添加管理员", key = "account", dict = UserDict.class)
    @ResponseBody
    public Tip add(@Valid UserDto user, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        // 判断账号是否重复
        User theUser = userService.getByAccount(user.getAccount());
        if (theUser != null) {
            throw new GunsException(BizExceptionEnum.USER_ALREADY_REG);
        }
        // 完善账号信息
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(user.getPassword(), user.getSalt()));
        user.setStatus(ManagerStatus.OK.getCode());
        user.setCreatetime(new Date());
        this.userService.insert(UserFactory.createUser(user));
        return SUCCESS_TIP;
    }
    /**
     * 修改管理员
     *
     * @throws NoPermissionException
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/edit")
    @BussinessLog(value = "修改管理员", key = "account", dict = UserDict.class)
    @ResponseBody
    public Tip edit(@Valid UserDto user, BindingResult result) throws NoPermissionException {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        User oldUser = userService.selectById(user.getId());
        if (ShiroKit.hasRole(Const.ADMIN_NAME)) {
            this.userService.updateById(UserFactory.editUser(user, oldUser));
            return SUCCESS_TIP;
        } else {
            assertAuth(user.getId());
            ShiroUser shiroUser = ShiroKit.getUser();
            if (shiroUser.getId().equals(user.getId())) {
                this.userService.updateById(UserFactory.editUser(user, oldUser));
                return SUCCESS_TIP;
            } else {
                throw new GunsException(BizExceptionEnum.NO_PERMITION);
            }
        }
    }
    /**
     * 删除管理员(逻辑删除)
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/delete")
    @BussinessLog(value = "删除管理员", key = "userId", dict = UserDict.class)
    @ResponseBody
    public Tip delete(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能删除超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new GunsException(BizExceptionEnum.CANT_DELETE_ADMIN);
        }
        assertAuth(userId);
        User user1 = userService.selectById(userId);
        this.userService.setStatus(userId, ManagerStatus.DELETED.getCode());
        User user = userService.selectById(userId);
        return SUCCESS_TIP;
    }
    /**
     * 查看管理员详情
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/view/{userId}")
    @ResponseBody
    public User view(@PathVariable Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        return this.userService.selectById(userId);
    }
    /**
     * 重置管理员的密码
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/reset")
    @BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class)
    @ResponseBody
    public Tip reset(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        User user = this.userService.selectById(userId);
        User user1 = new User();
        BeanUtils.copyProperties(user, user1);
        user.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
        user.setUpdatePasswordTime(new Date());
        this.userService.updateById(user);
        return SUCCESS_TIP;
    }
    /**
     * 冻结用户
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/freeze")
    @BussinessLog(value = "冻结用户", key = "userId", dict = UserDict.class)
    @ResponseBody
    public Tip freeze(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能冻结超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new GunsException(BizExceptionEnum.CANT_FREEZE_ADMIN);
        }
        assertAuth(userId);
        User user1 = userService.selectById(userId);
        this.userService.setStatus(userId, ManagerStatus.FREEZED.getCode());
        User user = userService.selectById(userId);
        return SUCCESS_TIP;
    }
    /**
     * 解除冻结用户
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/unfreeze")
    @BussinessLog(value = "解除冻结用户", key = "userId", dict = UserDict.class)
    @ResponseBody
    public Tip unfreeze(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        User user1 = userService.selectById(userId);
        this.userService.setStatus(userId, ManagerStatus.OK.getCode());
        User user = userService.selectById(userId);
        return SUCCESS_TIP;
    }
    /**
     * 分配角色
     */
    @DataSource(name = "dataSourceGuns")
    @RequestMapping("/setRole")
    @BussinessLog(value = "分配角色", key = "userId,roleIds", dict = UserDict.class)
    @ResponseBody
    public Tip setRole(@RequestParam("userId") Integer userId, @RequestParam("roleIds") String roleIds) {
        if (ToolUtil.isOneEmpty(userId, roleIds)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //不能修改超级管理员
        if (userId.equals(Const.ADMIN_ID)) {
            throw new GunsException(BizExceptionEnum.CANT_CHANGE_ADMIN);
        }
        assertAuth(userId);
        this.userService.setRoles(userId, roleIds);
        User user = userService.selectById(userId);
        return SUCCESS_TIP;
    }
    /**
     * 上传图片
     */
    @RequestMapping(method = RequestMethod.POST, path = "/upload")
    @ResponseBody
    public String upload(@RequestPart("file") MultipartFile picture) {
        String pictureName = UUID.randomUUID().toString() + "." + ToolUtil.getFileSuffix(picture.getOriginalFilename());
        try {
            String fileSavePath = gunsProperties.getFileUploadPath();
            picture.transferTo(new File(fileSavePath + pictureName));
        } catch (Exception e) {
            throw new GunsException(BizExceptionEnum.UPLOAD_ERROR);
        }
        return pictureName;
    }
    /**
     * 判断当前登录的用户是否有操作这个用户的权限
     */
    private void assertAuth(Integer userId) {
        if (ShiroKit.isAdmin()) {
            return;
        }
        List<Integer> deptDataScope = ShiroKit.getDeptDataScope();
        User user = this.userService.selectById(userId);
        Integer deptid = user.getDeptid();
        if (deptDataScope.contains(deptid)) {
            return;
        } else {
            throw new GunsException(BizExceptionEnum.NO_PERMITION);
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/AppUserMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
public interface AppUserMapper extends BaseMapper<AppUser> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/BannerMapper.java
New file
@@ -0,0 +1,22 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Banner;
import com.stylefeng.guns.modular.system.warpper.res.BannerRes;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 16:40
 */
public interface BannerMapper extends BaseMapper<Banner> {
    /**
     * 获取banner
     * @param position
     * @return
     */
    List<BannerRes> getBanners(Integer position);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CollectionHouseResourceMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.CollectionHouseResource;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 17:32
 */
public interface CollectionHouseResourceMapper extends BaseMapper<CollectionHouseResource> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/CollectionHousingDemandMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.CollectionHousingDemand;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:46
 */
public interface CollectionHousingDemandMapper extends BaseMapper<CollectionHousingDemand> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/DeptMapper.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Dept;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 部门表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface DeptMapper extends BaseMapper<Dept> {
    /**
     * 获取ztree的节点列表
     */
    List<ZTreeNode> tree();
    /**
     * 获取所有部门列表
     */
    List<Map<String, Object>> list(@Param("condition") String condition);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/DictMapper.java
New file
@@ -0,0 +1,34 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Dict;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 字典表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface DictMapper extends BaseMapper<Dict> {
    /**
     * 根据编码获取词典列表
     */
    List<Dict> selectByCode(@Param("code") String code);
    /**
     * 查询字典列表
     */
    List<Map<String, Object>> list(@Param("condition") String conditiion);
    /**
     * 根据父类编码获取词典列表
     */
    List<Dict> selectByParentCode(@Param("code") String code);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/EncyclopedicKnowledgeMapper.java
New file
@@ -0,0 +1,23 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledge;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeRes;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:18
 */
public interface EncyclopedicKnowledgeMapper extends BaseMapper<EncyclopedicKnowledge> {
    /**
     * 获取列表图片
     * @param typeId
     * @return
     */
    List<EncyclopedicKnowledgeRes> getEncyclopedicKnowledgeList(@Param("typeId") Integer typeId);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/EncyclopedicKnowledgeUpvoteMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledgeUpvote;
/**
 * @author zhibing.pu
 * @Date 2023/11/24 17:28
 */
public interface EncyclopedicKnowledgeUpvoteMapper extends BaseMapper<EncyclopedicKnowledgeUpvote> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ExpenseMapper.java
New file
@@ -0,0 +1,16 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Expense;
/**
 * <p>
  * 报销表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-12-04
 */
public interface ExpenseMapper extends BaseMapper<Expense> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HouseResourceMapper.java
New file
@@ -0,0 +1,53 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.HouseResource;
import com.stylefeng.guns.modular.system.warpper.req.SearchHouseResourceReq;
import com.stylefeng.guns.modular.system.warpper.res.DistrictHouseResourceNumberRes;
import com.stylefeng.guns.modular.system.warpper.res.SearchHouseResourceListRes;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/8 15:09
 */
public interface HouseResourceMapper extends BaseMapper<HouseResource> {
    /**
     * 获取房源列表数据
     * @param req
     * @return
     */
    List<SearchHouseResourceListRes> searchHouseResource(@Param("req") SearchHouseResourceReq req, @Param("cityIds") List<Integer> cityIds,
                                                         @Param("districtIds") List<Integer> districtIds,
                                                         @Param("saleAmountStart") Double saleAmountStart, @Param("saleAmountEnd") Double saleAmountEnd,
                                                         @Param("houseModels") List<String> houseModels, @Param("houseTypeIds") List<Integer> houseTypeIds);
    /**
     * 获取房源列表总数量
     * @param req
     * @param saleAmountStart
     * @param saleAmountEnd
     * @param houseModels
     * @param houseTypeIds
     * @return
     */
    Integer searchHouseResourceCount(@Param("req") SearchHouseResourceReq req, @Param("cityIds") List<Integer> cityIds,
                                     @Param("districtIds") List<Integer> districtIds,
                                     @Param("saleAmountStart") Double saleAmountStart, @Param("saleAmountEnd") Double saleAmountEnd,
                                     @Param("houseModels") List<String> houseModels, @Param("houseTypeIds") List<Integer> houseTypeIds);
    /**
     * 获取行政区域房源数量
     * @param userType
     * @param dataType
     * @return
     */
    List<DistrictHouseResourceNumberRes> getDistrictHouseResourceNumber(@Param("userType") Integer userType, @Param("dataType") Integer dataType);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HouseTypeMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.HouseType;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 14:44
 */
public interface HouseTypeMapper extends BaseMapper<HouseType> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HousingDemandDistrictMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.HousingDemandDistrict;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 9:48
 */
public interface HousingDemandDistrictMapper extends BaseMapper<HousingDemandDistrict> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/HousingDemandMapper.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.HousingDemand;
import com.stylefeng.guns.modular.system.warpper.req.SearchHousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandListRes;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 16:58
 */
public interface HousingDemandMapper extends BaseMapper<HousingDemand> {
    /**
     * 搜索求房源列表数据
     * @param req
     * @param district
     * @param saleAmountStart
     * @param saleAmountEnd
     * @param houseModels
     * @param houseTypeIds
     * @return
     */
    List<SearchHousingDemandListRes> searchHousingDemand(@Param("req") SearchHousingDemandReq req, @Param("district") List<String> district,
                                                         @Param("saleAmountStart") Double saleAmountStart, @Param("saleAmountEnd") Double saleAmountEnd,
                                                         @Param("houseModels") List<String> houseModels, @Param("houseTypeIds") List<Integer> houseTypeIds);
    Integer searchHousingDemandCount(@Param("req") SearchHousingDemandReq req, @Param("district") List<String> district,
                                     @Param("saleAmountStart") Double saleAmountStart, @Param("saleAmountEnd") Double saleAmountEnd,
                                     @Param("houseModels") List<String> houseModels, @Param("houseTypeIds") List<Integer> houseTypeIds);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/LoginLogMapper.java
New file
@@ -0,0 +1,27 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.modular.system.model.LoginLog;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 登录记录 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface LoginLogMapper extends BaseMapper<LoginLog> {
    /**
     * 获取登录日志
     */
    List<Map<String, Object>> getLoginLogs(@Param("page") Page<LoginLog> page, @Param("beginTime") String beginTime,
                                           @Param("endTime") String endTime, @Param("logName") String logName, @Param("orderByField") String orderByField, @Param("isAsc") boolean isAsc);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/MenuMapper.java
New file
@@ -0,0 +1,80 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.core.node.MenuNode;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Menu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
  * 菜单表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface MenuMapper extends BaseMapper<Menu> {
    /**
     * 根据条件查询菜单
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Map<String, Object>> selectMenus(@Param("condition") String condition, @Param("level") String level);
    /**
     * 根据条件查询菜单
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Long> getMenuIdsByRoleId(@Param("roleId") Integer roleId);
    /**
     * 获取菜单列表树
     *
     * @return
     * @date 2017年2月19日 下午1:33:51
     */
    List<ZTreeNode> menuTreeList();
    /**
     * 获取菜单列表树
     *
     * @return
     * @date 2017年2月19日 下午1:33:51
     */
    List<ZTreeNode> menuTreeListByMenuIds(List<Long> menuIds);
    /**
     * 删除menu关联的relation
     *
     * @param menuId
     * @return
     * @date 2017年2月19日 下午4:10:59
     */
    int deleteRelationByMenu(Long menuId);
    /**
     * 获取资源url通过角色id
     *
     * @param roleId
     * @return
     * @date 2017年2月19日 下午7:12:38
     */
    List<String> getResUrlsByRoleId(Integer roleId);
    /**
     * 根据角色获取菜单
     *
     * @param roleIds
     * @return
     * @date 2017年2月19日 下午10:35:40
     */
    List<MenuNode> getMenusByRoleIds(List<Integer> roleIds);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/NoticeMapper.java
New file
@@ -0,0 +1,25 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Notice;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 通知表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface NoticeMapper extends BaseMapper<Notice> {
    /**
     * 获取通知列表
     */
    List<Map<String, Object>> list(@Param("condition") String condition);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/OperationLogMapper.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.stylefeng.guns.modular.system.model.OperationLog;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 操作日志 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface OperationLogMapper extends BaseMapper<OperationLog> {
    /**
     * 获取操作日志
     */
    List<Map<String, Object>> getOperationLogs(@Param("page") Page<OperationLog> page, @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("logName") String logName, @Param("logType") String logType, @Param("orderByField") String orderByField, @Param("isAsc") boolean isAsc);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RegionMapper.java
New file
@@ -0,0 +1,18 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Region;
import com.stylefeng.guns.modular.system.warpper.res.DistrictRes;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface RegionMapper extends BaseMapper<Region> {
    /**
     * 获取行政区划数据
     * @param parentId
     * @return
     */
    List<DistrictRes> getDistrict(@Param("parentId") Integer parentId);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RelationMapper.java
New file
@@ -0,0 +1,16 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.Relation;
/**
 * <p>
  * 角色和菜单关联表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface RelationMapper extends BaseMapper<Relation> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ReportHouseResourceMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.ReportHouseResource;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 15:29
 */
public interface ReportHouseResourceMapper extends BaseMapper<ReportHouseResource> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/ReportHousingDemandMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.ReportHousingDemand;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:53
 */
public interface ReportHousingDemandMapper extends BaseMapper<ReportHousingDemand> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/RoleMapper.java
New file
@@ -0,0 +1,53 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Role;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
  * 角色表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface RoleMapper extends BaseMapper<Role> {
    /**
     * 根据条件查询角色列表
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Map<String, Object>> selectRoles(@Param("condition") String condition);
    /**
     * 删除某个角色的所有权限
     *
     * @param roleId 角色id
     * @return
     * @date 2017年2月13日 下午7:57:51
     */
    int deleteRolesById(@Param("roleId") Integer roleId);
    /**
     * 获取角色列表树
     *
     * @return
     * @date 2017年2月18日 上午10:32:04
     */
    List<ZTreeNode> roleTreeList();
    /**
     * 获取角色列表树
     *
     * @return
     * @date 2017年2月18日 上午10:32:04
     */
    List<ZTreeNode> roleTreeListByRoleId(String[] roleId);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/SearchHistoryConditionMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.SearchHistoryCondition;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 11:00
 */
public interface SearchHistoryConditionMapper extends BaseMapper<SearchHistoryCondition> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/SysDataTypeMapper.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.modular.system.model.SysDataType;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:22
 */
public interface SysDataTypeMapper extends BaseMapper<SysDataType> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/UserMapper.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.stylefeng.guns.core.datascope.DataScope;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 管理员表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface UserMapper extends BaseMapper<User> {
    /**
     * 修改用户状态
     */
    int setStatus(@Param("userId") Integer userId, @Param("status") int status);
    /**
     * 修改密码
     */
    int changePwd(@Param("userId") Integer userId, @Param("pwd") String pwd);
    /**
     * 根据条件查询用户列表
     */
    List<Map<String, Object>> selectUsers(@Param("dataScope") DataScope dataScope, @Param("name") String name, @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("deptid") Integer deptid);
    /**
     * 设置用户的角色
     */
    int setRoles(@Param("userId") Integer userId, @Param("roleIds") String roleIds);
    /**
     * 通过账号获取用户
     */
    User getByAccount(@Param("account") String account);
    Map<String, Object> getSysUserDetails(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/AppUserMapper.xml
New file
@@ -0,0 +1,7 @@
<?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.stylefeng.guns.modular.system.dao.AppUserMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/BannerMapper.xml
New file
@@ -0,0 +1,10 @@
<?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.stylefeng.guns.modular.system.dao.BannerMapper">
    <select id="getBanners" resultType="com.stylefeng.guns.modular.system.warpper.res.BannerRes">
        select id, img_url as imgUrl, content from t_banner where `position` = #{position} order by `sort` desc
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CollectionHouseResourceMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.CollectionHouseResourceMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/CollectionHousingDemandMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.CollectionHousingDemandMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/DeptMapper.xml
New file
@@ -0,0 +1,37 @@
<?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.stylefeng.guns.modular.system.dao.DeptMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Dept">
        <id column="id" property="id"/>
        <result column="num" property="num"/>
        <result column="pid" property="pid"/>
        <result column="pids" property="pids"/>
        <result column="simplename" property="simplename"/>
        <result column="fullname" property="fullname"/>
        <result column="tips" property="tips"/>
        <result column="version" property="version"/>
    </resultMap>
    <select id="tree" resultType="com.stylefeng.guns.core.node.ZTreeNode">
        select id,pid as pId,simplename as name,
        (
        CASE
        WHEN (pId = 0 OR pId IS NULL) THEN
        'true'
        ELSE
        'false'
        END
        ) as isOpen from sys_dept
    </select>
    <select id="list" resultType="map">
        select * from sys_dept
        <if test="condition != null and condition != ''">
            where simplename like CONCAT('%',#{condition},'%') or fullname like CONCAT('%',#{condition},'%')
        </if>
        order by num ASC
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/DictMapper.xml
New file
@@ -0,0 +1,42 @@
<?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.stylefeng.guns.modular.system.dao.DictMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Dict">
        <id column="id" property="id"/>
        <result column="num" property="num"/>
        <result column="pid" property="pid"/>
        <result column="name" property="name"/>
        <result column="code" property="code"/>
        <result column="tips" property="tips"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, num, pid, name,code,tips
    </sql>
    <select id="selectByCode" resultType="com.stylefeng.guns.modular.system.model.Dict">
        select
        <include refid="Base_Column_List"/>
        from sys_dict
        where code = #{code}
    </select>
    <select id="selectByParentCode" resultType="com.stylefeng.guns.modular.system.model.Dict">
        select
        <include refid="Base_Column_List"/>
        from sys_dict
        where pid in(select id  from sys_dict where code = #{code}) order by num asc
    </select>
    <select id="list" resultType="map">
        select * from sys_dict
        where pid = 0
        <if test="condition != null and condition != ''">
            AND name like CONCAT('%',#{condition},'%')
        </if>
        order by id ASC
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/EncyclopedicKnowledgeMapper.xml
New file
@@ -0,0 +1,14 @@
<?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.stylefeng.guns.modular.system.dao.EncyclopedicKnowledgeMapper">
    <select id="getEncyclopedicKnowledgeList" resultType="com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeRes">
        select
        id,
        title,
        img_url as imgUrl,
        content_text as content
        from t_encyclopedic_knowledge where sys_data_type_id = #{typeId} order by insert_time desc
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/EncyclopedicKnowledgeUpvoteMapper.xml
New file
@@ -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.stylefeng.guns.modular.system.dao.EncyclopedicKnowledgeUpvoteMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ExpenseMapper.xml
New file
@@ -0,0 +1,20 @@
<?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.stylefeng.guns.modular.system.dao.ExpenseMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Expense">
        <id column="id" property="id" />
        <result column="money" property="money" />
        <result column="desc" property="desc" />
        <result column="createtime" property="createtime" />
        <result column="state" property="state" />
        <result column="userid" property="userid" />
    </resultMap>
    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, money, desc, createtime, state, userid
    </sql>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HouseResourceMapper.xml
New file
@@ -0,0 +1,234 @@
<?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.stylefeng.guns.modular.system.dao.HouseResourceMapper">
    <select id="searchHouseResource" resultType="com.stylefeng.guns.modular.system.warpper.res.SearchHouseResourceListRes">
        select
        hr.id,
        au.user_type as houseResource,
        hr.house_photo as imgUrl,
        hr.title,
        hr.house_area as houseArea,
        hr.house_model as houseModel,
        concat(rp.`name`, rc.`name`) as address,
        hr.longitude,
        hr.latitude,
        hr.sale_amount as saleAmount,
        au.profile_photo as profilePhoto,
        au.nickname,
        hr.elevator,
        hr.drying_area as dryingArea,
        hr.garden,
        hr.carport,
        hr.balcony,
        hr.keep_pet as keepPet
        from t_house_resource hr
        left join t_app_user au on (hr.app_user_id = au.id)
        left join t_region rc on (hr.district_id = rc.id)
        left join t_region rp on (rp.id = rc.parent_id)
        where hr.is_delete = 0 and hr.`status` = 1 and hr.auth_status = 2
        <if test="null != req.type">
            and hr.data_type = #{req.type}
        </if>
        <if test="null != req.userType and 4 != req.userType">
            and au.user_type = #{req.userType}
        </if>
        <if test="null != req.userType and 4 == req.userType">
            and hr.firm_house = 1
        </if>
        <if test="null != req.content and '' != req.content">
            and hr.title = CONCAT('%', #{req.content}, '%')
        </if>
        <if test="null != cityIds">
            and hr.city_id in
            <foreach collection="cityIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != districtIds">
            and hr.district_id in
            <foreach collection="districtIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != saleAmountStart and null != saleAmountEnd">
            and hr.sale_amount &gt;= #{saleAmountStart} and hr.sale_amount &lt; #{saleAmountEnd}
        </if>
        <if test="null != houseModels">
            and hr.house_model in
            <foreach collection="houseModels" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.elevator">
            and hr.elevator = #{req.elevator}
        </if>
        <if test="null != houseTypeIds">
            and hr.house_type_id in
            <foreach collection="houseTypeIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.rentalDuration">
            and hr.rental_duration = #{req.rentalDuration}
        </if>
        <if test="null != req.balcony">
            and hr.balcony = #{req.balcony}
        </if>
        <if test="null != req.keepPet">
            and hr.keep_pet = #{req.keepPet}
        </if>
        <if test="null != req.createTime and req.createTime == 3">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 3 day)
        </if>
        <if test="null != req.createTime and req.createTime == 7">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 7 day)
        </if>
        <if test="null != req.createTime and req.createTime == 30">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 1 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 60">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 2 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 90">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 3 MONTH)
        </if>
        <if test="null != req.dataType and req.dataType == 1">
            and hr.good_house = 1
        </if>
        <if test="null != req.dataType and req.dataType == 2">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 7 day)
        </if>
        <if test="null != req.sort and req.sort == 1">
            order by hr.insert_time desc
        </if>
        <if test="null != req.sort and req.sort == 2">
            order by hr.good_house desc
        </if>
        <if test="null != req.sort and req.sort == 3">
            order by hr.sale_amount
        </if>
        <if test="null != req.sort and req.sort == 4">
            order by hr.sale_amount desc
        </if>
        limit #{req.pageNum}, #{req.pageSize}
    </select>
    <select id="searchHouseResourceCount" resultType="int">
        select
        count(1)
        from t_house_resource hr
        left join t_app_user au on (hr.app_user_id = au.id)
        where hr.is_delete = 0 and hr.`status` = 1 and hr.auth_status = 2
        <if test="null != req.type">
            and hr.data_type = #{req.type}
        </if>
        <if test="null != req.userType and 4 != req.userType">
            and au.user_type = #{req.userType}
        </if>
        <if test="null != req.userType and 4 == req.userType">
            and hr.firm_house = 1
        </if>
        <if test="null != req.content and '' != req.content">
            and hr.title = CONCAT('%', #{req.content}, '%')
        </if>
        <if test="null != cityIds">
            and hr.city_id in
            <foreach collection="cityIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != districtIds">
            and hr.district_id in
            <foreach collection="districtIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != saleAmountStart and null != saleAmountEnd">
            and hr.sale_amount &gt;= #{saleAmountStart} and hr.sale_amount &lt; #{saleAmountEnd}
        </if>
        <if test="null != houseModels">
            and hr.house_model in
            <foreach collection="houseModels" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.elevator">
            and hr.elevator = #{req.elevator}
        </if>
        <if test="null != houseTypeIds">
            and hr.house_type_id in
            <foreach collection="houseTypeIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.rentalDuration">
            and hr.rental_duration = #{req.rentalDuration}
        </if>
        <if test="null != req.balcony">
            and hr.balcony = #{req.balcony}
        </if>
        <if test="null != req.keepPet">
            and hr.keep_pet = #{req.keepPet}
        </if>
        <if test="null != req.createTime and req.createTime == 3">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 3 day)
        </if>
        <if test="null != req.createTime and req.createTime == 7">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 7 day)
        </if>
        <if test="null != req.createTime and req.createTime == 30">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 1 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 60">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 2 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 90">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 3 MONTH)
        </if>
        <if test="null != req.dataType and req.dataType == 1">
            and hr.good_house = 1
        </if>
        <if test="null != req.dataType and req.dataType == 2">
            and now() &lt;= DATE_ADD(hr.insert_time,INTERVAL 7 day)
        </if>
    </select>
    <select id="getDistrictHouseResourceNumber" resultType="com.stylefeng.guns.modular.system.warpper.res.DistrictHouseResourceNumberRes">
        select
        r.name,
        r.id as districtId,
        pr.id as cityId,
        dn.number,
        r.longitude,
        r.latitude
        from (
            select
            hr.district_id,
            count(hr.id) as number
            from t_house_resource hr
            left join t_app_user au on (hr.app_user_id = au.id)
            where hr.is_delete = 0 and hr.`status` = 1 and hr.auth_status = 2
            <if test="null != userType and 4 != userType">
                and au.user_type = #{userType} and au.status = 1 and au.audit_status = 2
            </if>
            <if test="null != userType and 4 == userType">
                and hr.firm_house = 1
            </if>
            <if test="null != dataType">
                and hr.data_type = #{dataType}
            </if>
            group by hr.district_id
        ) as dn
        left join t_region r on (dn.district_id = r.id)
        left join t_region pr on (pr.id = r.parent_id)
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HouseTypeMapper.xml
New file
@@ -0,0 +1,4 @@
<?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.stylefeng.guns.modular.system.dao.HouseTypeMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HousingDemandDistrictMapper.xml
New file
@@ -0,0 +1,4 @@
<?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.stylefeng.guns.modular.system.dao.HousingDemandDistrictMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/HousingDemandMapper.xml
New file
@@ -0,0 +1,153 @@
<?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.stylefeng.guns.modular.system.dao.HousingDemandMapper">
    <select id="searchHousingDemand" resultType="com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandListRes">
        select
        hd.id,
        hd.title,
        hd.house_model as houseModel,
        hd.sale_amount as saleAmount,
        au.profile_photo as profilePhoto,
        au.nickname,
        hd.elevator,
        hd.drying_area as dryingArea,
        hd.garden,
        hd.carport,
        hd.balcony,
        hd.keep_pet as keepPet
        from t_housing_demand hd
        left join t_app_user au on (hd.app_user_id = au.id)
        where hd.`status` = 1 and hd.is_delete = 0
        <if test="null != req.type">
            and hd.data_type = #{req.type}
        </if>
        <if test="null != req.content and '' != req.content">
            and hd.title = CONCAT('%', #{req.content}, '%')
        </if>
        <if test="null != district and '' != district">
            and hd.id in (select housing_demand_id from t_housing_demand_district where CONCAT('cityId:', city_id, ',districtId:', district_id) in
            <foreach collection="district" item="item" index="index" open="(" separator="," close=")">
                #{item}
            </foreach>
            )
        </if>
        <if test="null != saleAmountStart and null != saleAmountEnd">
            and hd.sale_amount &gt;= #{saleAmountStart} and hd.sale_amount &lt; #{saleAmountEnd}
        </if>
        <if test="null != houseModels">
            and hd.house_model in
            <foreach collection="houseModels" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != houseTypeIds">
            and hd.house_type_id in
            <foreach collection="houseTypeIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.elevator">
            and hd.elevator = #{req.elevator}
        </if>
        <if test="null != req.rentalDuration">
            and hd.rental_duration = #{req.rentalDuration}
        </if>
        <if test="null != req.balcony">
            and hd.balcony = #{req.balcony}
        </if>
        <if test="null != req.keepPet">
            and hd.keep_pet = #{req.keepPet}
        </if>
        <if test="null != req.createTime and req.createTime == 3">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 3 day)
        </if>
        <if test="null != req.createTime and req.createTime == 7">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 7 day)
        </if>
        <if test="null != req.createTime and req.createTime == 30">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 1 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 60">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 2 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 90">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 3 MONTH)
        </if>
        <if test="null != req.sort and req.sort == 1">
            order by hd.insert_time desc
        </if>
        <if test="null != req.sort and req.sort == 3">
            order by hd.sale_amount
        </if>
        <if test="null != req.sort and req.sort == 4">
            order by hd.sale_amount desc
        </if>
        limit #{req.pageNum}, #{req.pageSize}
    </select>
    <select id="searchHousingDemandCount" resultType="int">
        select
        count(1)
        from t_housing_demand hd
        where hd.`status` = 1 and hd.is_delete = 0
        <if test="null != req.type">
            and hd.data_type = #{req.type}
        </if>
        <if test="null != req.content and '' != req.content">
            and hd.title = CONCAT('%', #{req.content}, '%')
        </if>
        <if test="null != district and '' != district">
            and hd.id in (select housing_demand_id from t_housing_demand_district where CONCAT('cityId:', city_id, ',districtId:', district_id) in
            <foreach collection="district" item="item" index="index" open="(" separator="," close=")">
                #{item}
            </foreach>
            )
        </if>
        <if test="null != saleAmountStart and null != saleAmountEnd">
            and hd.sale_amount &gt;= #{saleAmountStart} and hd.sale_amount &lt; #{saleAmountEnd}
        </if>
        <if test="null != houseModels">
            and hd.house_model in
            <foreach collection="houseModels" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != houseTypeIds">
            and hd.house_type_id in
            <foreach collection="houseTypeIds" item="item" index="index" separator="," open="(" close=")">
                #{item}
            </foreach>
        </if>
        <if test="null != req.elevator">
            and hd.elevator = #{req.elevator}
        </if>
        <if test="null != req.rentalDuration">
            and hd.rental_duration = #{req.rentalDuration}
        </if>
        <if test="null != req.balcony">
            and hd.balcony = #{req.balcony}
        </if>
        <if test="null != req.keepPet">
            and hd.keep_pet = #{req.keepPet}
        </if>
        <if test="null != req.createTime and req.createTime == 3">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 3 day)
        </if>
        <if test="null != req.createTime and req.createTime == 7">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 7 day)
        </if>
        <if test="null != req.createTime and req.createTime == 30">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 1 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 60">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 2 MONTH)
        </if>
        <if test="null != req.createTime and req.createTime == 90">
            and now() &lt;= DATE_ADD(hd.insert_time,INTERVAL 3 MONTH)
        </if>
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/LoginLogMapper.xml
New file
@@ -0,0 +1,41 @@
<?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.stylefeng.guns.modular.system.dao.LoginLogMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.LoginLog">
        <id column="id" property="id" />
        <result column="logname" property="logname" />
        <result column="userid" property="userid" />
        <result column="createtime" property="createtime" />
        <result column="succeed" property="succeed" />
        <result column="message" property="message" />
        <result column="ip" property="ip" />
    </resultMap>
    <select id="getLoginLogs" resultType="map" parameterType="com.baomidou.mybatisplus.plugins.Page">
        select * from sys_login_log where 1 = 1
        <if test="beginTime != null and beginTime !='' and endTime != null and endTime != ''">
            and (createTime between CONCAT(#{beginTime},' 00:00:00') and CONCAT(#{endTime},' 23:59:59'))
        </if>
        <if test="logName != null and logName !=''">
            and logname like CONCAT('%',#{logName},'%')
        </if>
        <choose>
            <when test="orderByField != null and orderByField !=''">
                <choose>
                    <when test="isAsc == true">
                        order by ${orderByField} ASC
                    </when>
                    <otherwise>
                        order by ${orderByField} DESC
                    </otherwise>
                </choose>
            </when>
            <otherwise>
                order by createtime DESC
            </otherwise>
        </choose>
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/MenuMapper.xml
New file
@@ -0,0 +1,177 @@
<?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.stylefeng.guns.modular.system.dao.MenuMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Menu">
        <id column="id" property="id" />
        <result column="code" property="code" />
        <result column="pcode" property="pcode" />
        <result column="pcodes" property="pcodes" />
        <result column="name" property="name" />
        <result column="icon" property="icon" />
        <result column="url" property="url" />
        <result column="num" property="num" />
        <result column="levels" property="levels" />
        <result column="ismenu" property="ismenu" />
        <result column="tips" property="tips" />
        <result column="status" property="status" />
        <result column="isopen" property="isopen" />
    </resultMap>
    <sql id="Base_Column_List">
        id, code, pcode, name, icon, url, num, levels,pcodes,
        tips, status,isopen,ismenu
    </sql>
    <select id="selectMenus" resultType="map">
        select
        <include refid="Base_Column_List" />
        from sys_menu
        where status = 1
        <if test="condition != null and condition != ''">
            and (name like CONCAT('%',#{condition},'%') or code like CONCAT('%',#{condition},'%'))
        </if>
        <if test="level != null and level != ''">
            and levels = #{level}
        </if>
    </select>
    <select id="getMenuIdsByRoleId" resultType="long">
        select menuid from
        sys_relation where roleid = #{roleId}
    </select>
    <select id="menuTreeList" resultType="com.stylefeng.guns.core.node.ZTreeNode">
        SELECT
        m1.id AS id,
        (
        CASE
        WHEN (m2.id = 0 OR m2.id IS NULL) THEN
        0
        ELSE
        m2.id
        END
        ) AS pId,
        m1. NAME
        AS NAME,
        (
        CASE
        WHEN (m2.id = 0 OR m2.id IS NULL) THEN
        'true'
        ELSE
        'false'
        END
        ) as isOpen
        FROM
        sys_menu m1
        LEFT join sys_menu m2 ON m1.pcode = m2. CODE
        ORDER BY
        m1.id ASC
    </select>
    <select id="menuTreeListByMenuIds" resultType="com.stylefeng.guns.core.node.ZTreeNode">
        SELECT
        m1.id AS id,
        (
        CASE
        WHEN (m2.id = 0 OR m2.id IS NULL) THEN
        0
        ELSE
        m2.id
        END
        ) AS pId,
        m1. NAME AS NAME,
        (
        CASE
        WHEN (m2.id = 0 OR m2.id IS
        NULL) THEN
        'true'
        ELSE
        'false'
        END
        ) as isOpen,
        (
        CASE
        WHEN (m3.ID = 0 OR m3.ID
        IS NULL) THEN
        'false'
        ELSE
        'true'
        END
        ) "checked"
        FROM
        sys_menu m1
        LEFT JOIN
        sys_menu m2
        ON m1.pcode = m2. CODE
        left join (
        SELECT
        ID
        FROM
        sys_menu
        WHERE
        ID IN
        <foreach collection="list" index="index" item="i" open="("
                 separator="," close=")">
            #{i}
        </foreach>
        ) m3 on m1.id = m3.id
        ORDER BY
        m1.id ASC
    </select>
    <delete id="deleteRelationByMenu">
        delete from sys_relation where menuid = #{menuId}
    </delete>
    <select id="getResUrlsByRoleId" resultType="string">
        select url from
        sys_relation rel
        inner join sys_menu m on rel.menuid = m.id
        where rel.roleid = #{roleId}
    </select>
    <select id="getMenusByRoleIds" resultType="com.stylefeng.guns.core.node.MenuNode">
        SELECT
        m1.id AS id,
        m1.icon AS icon,
        (
        CASE
        WHEN (m2.id = 0 OR m2.id IS NULL) THEN
        0
        ELSE
        m2.id
        END
        ) AS parentId,
        m1.NAME as name,
        m1.url as url,
        m1.levels as levels,
        m1.ismenu as ismenu,
        m1.num as num
        FROM
        sys_menu m1
        LEFT join sys_menu m2 ON m1.pcode = m2. CODE
        INNER JOIN (
        SELECT
        ID
        FROM
        sys_menu
        WHERE
        ID IN (
        SELECT
        menuid
        FROM
        sys_relation rela
        WHERE
        rela.roleid IN
        <foreach collection="list" index="index" item="i" open="(" separator="," close=")">
            #{i}
        </foreach>
        )
        ) m3 ON m1.id = m3.id
        where m1.ismenu = 1
        order by levels,num asc
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/NoticeMapper.xml
New file
@@ -0,0 +1,23 @@
<?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.stylefeng.guns.modular.system.dao.NoticeMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Notice">
        <id column="id" property="id"/>
        <result column="title" property="title"/>
        <result column="type" property="type"/>
        <result column="content" property="content"/>
        <result column="createtime" property="createtime"/>
        <result column="creater" property="creater"/>
    </resultMap>
    <select id="list" resultType="map">
        select * from sys_notice
        <if test="condition != null and condition != ''">
            where title like CONCAT('%',#{condition},'%') or content like CONCAT('%',#{condition},'%')
        </if>
        order by createtime DESC
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/OperationLogMapper.xml
New file
@@ -0,0 +1,46 @@
<?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.stylefeng.guns.modular.system.dao.OperationLogMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.OperationLog">
        <id column="id" property="id" />
        <result column="logtype" property="logtype" />
        <result column="logname" property="logname" />
        <result column="userid" property="userid" />
        <result column="classname" property="classname" />
        <result column="method" property="method" />
        <result column="createtime" property="createtime" />
        <result column="succeed" property="succeed" />
        <result column="message" property="message" />
    </resultMap>
    <select id="getOperationLogs" resultType="map">
        select * from sys_operation_log where 1 = 1
        <if test="beginTime != null and beginTime !='' and endTime != null and endTime != ''">
            and (createTime between CONCAT(#{beginTime},' 00:00:00') and CONCAT(#{endTime},' 23:59:59'))
        </if>
        <if test="logName != null and logName !=''">
            and logname like CONCAT('%',#{logName},'%')
        </if>
        <if test="logType != null and logType !=''">
            and logtype like CONCAT('%',#{logType},'%')
        </if>
        <choose>
            <when test="orderByField != null and orderByField !=''">
                <choose>
                    <when test="isAsc == true">
                        order by ${orderByField} ASC
                    </when>
                    <otherwise>
                        order by ${orderByField} DESC
                    </otherwise>
                </choose>
            </when>
            <otherwise>
                order by createtime DESC
            </otherwise>
        </choose>
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RegionMapper.xml
New file
@@ -0,0 +1,14 @@
<?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.stylefeng.guns.modular.system.dao.RegionMapper">
    <select id="getDistrict" resultType="com.stylefeng.guns.modular.system.warpper.res.DistrictRes">
      select
      id,
      `name`,
      code
      from  t_region where parent_id = #{parentId} order by code
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RelationMapper.xml
New file
@@ -0,0 +1,12 @@
<?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.stylefeng.guns.modular.system.dao.RelationMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Relation">
        <id column="id" property="id" />
        <result column="menuid" property="menuid" />
        <result column="roleid" property="roleid" />
    </resultMap>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReportHouseResourceMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.ReportHouseResourceMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/ReportHousingDemandMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.ReportHousingDemandMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/RoleMapper.xml
New file
@@ -0,0 +1,80 @@
<?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.stylefeng.guns.modular.system.dao.RoleMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.Role">
        <id column="id" property="id" />
        <result column="num" property="num" />
        <result column="pid" property="pid" />
        <result column="name" property="name" />
        <result column="deptid" property="deptid" />
        <result column="tips" property="tips" />
        <result column="version" property="version" />
    </resultMap>
    <sql id="Base_Column_List">
        id, num, pid, name, deptid, tips, version
    </sql>
    <select id="selectRoles" resultType="map">
        select
        <include refid="Base_Column_List" />
        from sys_role
        <if test="condition != null">
            where name like CONCAT('%',#{condition},'%')
        </if>
        order by id
    </select>
    <delete id="deleteRolesById">
        delete from sys_relation where roleid = #{roleId}
    </delete>
    <select id="roleTreeList" resultType="com.stylefeng.guns.core.node.ZTreeNode">
        select id "id",pId
        "pId",name as "name",(case when (pId=0 or pId is null) then 'true'
        else 'false' end) "open" from sys_role
    </select>
    <select id="roleTreeListByRoleId" resultType="com.stylefeng.guns.core.node.ZTreeNode">
        SELECT
        r.id "id",
        pId "pId",
        NAME AS "name",
        (
        CASE
        WHEN (pId = 0 OR pId IS NULL) THEN
        'true'
        ELSE
        'false'
        END
        ) "open",
        (
        CASE
        WHEN (r1.ID = 0 OR r1.ID IS NULL) THEN
        'false'
        ELSE
        'true'
        END
        ) "checked"
        FROM
        sys_role r
        LEFT JOIN (
        SELECT
        ID
        FROM
        sys_role
        WHERE
        ID IN
        <foreach collection="array" index="index" item="i" open="(" separator="," close=")">
            #{i}
        </foreach>
        ) r1 ON r.ID = r1.ID
        ORDER BY
        pId,
        num ASC
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/SearchHistoryConditionMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.SearchHistoryConditionMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/SysDataTypeMapper.xml
New file
@@ -0,0 +1,6 @@
<?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.stylefeng.guns.modular.system.dao.SysDataTypeMapper">
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/dao/mapping/UserMapper.xml
New file
@@ -0,0 +1,81 @@
<?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.stylefeng.guns.modular.system.dao.UserMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.stylefeng.guns.modular.system.model.User">
        <id column="id" property="id" />
        <result column="avatar" property="avatar" />
        <result column="account" property="account" />
        <result column="password" property="password" />
        <result column="salt" property="salt" />
        <result column="name" property="name" />
        <result column="birthday" property="birthday" />
        <result column="sex" property="sex" />
        <result column="email" property="email" />
        <result column="phone" property="phone" />
        <result column="roleid" property="roleid" />
        <result column="deptid" property="deptid" />
        <result column="status" property="status" />
        <result column="createtime" property="createtime" />
        <result column="version" property="version" />
        <result column="updatePasswordTime" property="updatePasswordTime"/>
    </resultMap>
    <sql id="Base_Column_List">
        id, account, name, birthday, sex, email, avatar,
        phone, roleid,
        deptid, status,
        createtime, version, updatePasswordTime
    </sql>
    <sql id="Base_Column_List_With_Pwd">
        id, account, name, birthday,password, sex, email, avatar,
        phone, roleid,salt,
        deptid, status,
        createtime, version, updatePasswordTime
    </sql>
    <select id="selectUsers" resultType="map">
        select
        <include refid="Base_Column_List" />
        from sys_user
        where status != 3
        <if test="name != null and name != ''">
            and (phone like CONCAT('%',#{name},'%')
            or account like CONCAT('%',#{name},'%')
            or name like CONCAT('%',#{name},'%'))
        </if>
        <if test="deptid != null and deptid != 0">
            and (deptid = #{deptid} or deptid in ( select id from sys_dept where pids like CONCAT('%[', #{deptid}, ']%') ))
        </if>
        <if test="beginTime != null and beginTime != '' and endTime != null and endTime != ''">
            and (createTime between CONCAT(#{beginTime},' 00:00:00') and CONCAT(#{endTime},' 23:59:59'))
        </if>
    </select>
    <update id="setStatus">
        update sys_user set status = #{status} where id =
        #{userId}
    </update>
    <update id="changePwd">
        update sys_user set password = #{pwd} where id =
        #{userId}
    </update>
    <update id="setRoles">
        update sys_user set roleid = #{roleIds} where id =
        #{userId}
    </update>
    <select id="getByAccount" resultType="com.stylefeng.guns.modular.system.model.User">
        select
        <include refid="Base_Column_List_With_Pwd" />
        from sys_user where account = #{account} and status != 3
    </select>
    <select id="getSysUserDetails" resultType="map">
        select * ,IF( sex = 1, '男', '女' ) sexName  FROM  sys_user  where  id=#{id}
    </select>
</mapper>
guns-admin/src/main/java/com/stylefeng/guns/modular/system/factory/UserFactory.java
New file
@@ -0,0 +1,60 @@
package com.stylefeng.guns.modular.system.factory;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.transfer.UserDto;
import org.springframework.beans.BeanUtils;
import java.util.Date;
/**
 * 用户创建工厂
 *
 * @author fengshuonan
 * @date 2017-05-05 22:43
 */
public class UserFactory {
    public static User createUser(UserDto userDto) {
        if (userDto == null) {
            return null;
        } else {
            User user = new User();
            BeanUtils.copyProperties(userDto, user);
            user.setUpdatePasswordTime(new Date());
            return user;
        }
    }
    public static User editUser(UserDto newUser, User oldUser) {
        if (newUser == null || oldUser == null) {
            return oldUser;
        } else {
            if (ToolUtil.isNotEmpty(newUser.getAccount())) {
                oldUser.setAccount(newUser.getAccount());
            }
            if (ToolUtil.isNotEmpty(newUser.getAvatar())) {
                oldUser.setAvatar(newUser.getAvatar());
            }
            if (ToolUtil.isNotEmpty(newUser.getName())) {
                oldUser.setName(newUser.getName());
            }
            if (ToolUtil.isNotEmpty(newUser.getBirthday())) {
                oldUser.setBirthday(newUser.getBirthday());
            }
            if (ToolUtil.isNotEmpty(newUser.getDeptid())) {
                oldUser.setDeptid(newUser.getDeptid());
            }
            if (ToolUtil.isNotEmpty(newUser.getSex())) {
                oldUser.setSex(newUser.getSex());
            }
            if (ToolUtil.isNotEmpty(newUser.getEmail())) {
                oldUser.setEmail(newUser.getEmail());
            }
            if (ToolUtil.isNotEmpty(newUser.getPhone())) {
                oldUser.setPhone(newUser.getPhone());
            }
            return oldUser;
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/AppUser.java
New file
@@ -0,0 +1,104 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
* APP用户
* @author pzb
* @Date 2021/12/1 12:03
*/
@Data
@TableName("db_user")
public class AppUser {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 编号
     */
    @TableField("code")
    private String code;
    /**
     * 头像
     */
    @TableField("profile_photo")
    private String profilePhoto;
    /**
     * 昵称
     */
    @TableField("nickname")
    private String nickname;
    /**
     * 用户类型(1=普通,2=房东,3=中介)
     */
    @TableField("user_type")
    private Integer userType;
    /**
     * 手机号
     */
    @TableField("phone")
    private String phone;
    /**
     * 微信openid
     */
    @TableField("wechat_openid")
    private String wechatOpenid;
    /**
     * 微信二维码
     */
    @TableField("wechat_qr_code")
    private String wechatQRCode;
    /**
     * WhatApp
     */
    @TableField("watch_app")
    private String watchApp;
    /**
     * 代理人牌照号
     */
    @TableField("agent_licence_code")
    private String agentLicenceCode;
    /**
     * 公司名称
     */
    @TableField("company_name")
    private String companyName;
    /**
     * 公司地址
     */
    @TableField("company_address")
    private String companyAddress;
    /**
     * 名片照
     */
    @TableField("business_card_photo")
    private String businessCardPhoto;
    /**
     * 审核状态(1=待审核,2=审核通过,3=审核拒绝)
     */
    @TableField("audit_status")
    private Integer auditStatus;
    /**
     * 审核注释
     */
    @TableField("audit_note")
    private String auditNote;
    /**
     * 状态(1=正常,2=冻结,3=删除)
     */
    @TableField("status")
    private Integer status;
    /**
     * 注册时间
     */
    @TableField("insert_time")
    private Date insertTime;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Banner.java
New file
@@ -0,0 +1,53 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 16:37
 */
@Data
@TableName("t_banner")
public class Banner {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 位置(1=首页,2=详情)
     */
    @TableField("position")
    private Integer position;
    /**
     * 图片路径
     */
    @TableField("img_url")
    private String imgUrl;
    /**
     * 富文本内容
     */
    @TableField("content")
    private String content;
    /**
     * 排序
     */
    @TableField("sort")
    private Integer sort;
    /**
     * 添加人id
     */
    @TableField("insert_user_id")
    private Integer insertUserId;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CollectionHouseResource.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 17:31
 */
@Data
@TableName("t_collection_house_resource")
public class CollectionHouseResource {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 房源id
     */
    @TableField("house_resource_id")
    private Integer houseResourceId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/CollectionHousingDemand.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:45
 */
@Data
@TableName("t_collection_housing_demand")
public class CollectionHousingDemand {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 求房源id
     */
    @TableField("housing_demand_id")
    private Integer housingDemandId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Dept.java
New file
@@ -0,0 +1,140 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
 * <p>
 * 部门表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_dept")
public class Dept extends Model<Dept> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 排序
     */
    private Integer num;
    /**
     * 父部门id
     */
    private Integer pid;
    /**
     * 父级ids
     */
    private String pids;
    /**
     * 简称
     */
    private String simplename;
    /**
     * 全称
     */
    private String fullname;
    /**
     * 提示
     */
    private String tips;
    /**
     * 版本(乐观锁保留字段)
     */
    private Integer version;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getPids() {
        return pids;
    }
    public void setPids(String pids) {
        this.pids = pids;
    }
    public String getSimplename() {
        return simplename;
    }
    public void setSimplename(String simplename) {
        this.simplename = simplename;
    }
    public String getFullname() {
        return fullname;
    }
    public void setFullname(String fullname) {
        this.fullname = fullname;
    }
    public String getTips() {
        return tips;
    }
    public void setTips(String tips) {
        this.tips = tips;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Dept{" +
            "id=" + id +
            ", num=" + num +
            ", pid=" + pid +
            ", pids=" + pids +
            ", simplename=" + simplename +
            ", fullname=" + fullname +
            ", tips=" + tips +
            ", version=" + version +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Dict.java
New file
@@ -0,0 +1,116 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
 * <p>
 * 字典表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_dict")
public class Dict extends Model<Dict> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 排序
     */
    private Integer num;
    /**
     * 父级字典
     */
    private Integer pid;
    /**
     * 名称
     */
    private String name;
    /**
     * 编码
     */
    private String code;
    /**
     * 提示
     */
    private String tips;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getTips() {
        return tips;
    }
    public void setTips(String tips) {
        this.tips = tips;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    @Override
    public String toString() {
        return "Dict{" +
                "id=" + id +
                ", num=" + num +
                ", pid=" + pid +
                ", name='" + name + '\'' +
                ", code='" + code + '\'' +
                ", tips='" + tips + '\'' +
                '}';
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/EncyclopedicKnowledge.java
New file
@@ -0,0 +1,58 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:15
 */
@Data
@TableName("t_encyclopedic_knowledge")
public class EncyclopedicKnowledge {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 数据类型id
     */
    @TableField("sys_data_type_id")
    private Integer sysDataTypeId;
    /**
     * 标题
     */
    @TableField("title")
    private String title;
    /**
     * 列表图片
     */
    @TableField("img_url")
    private String imgUrl;
    /**
     * 富文本内容
     */
    @TableField("content")
    private String content;
    /**
     * 纯文本内容
     */
    @TableField("content_text")
    private String contentText;
    /**
     * 浏览数量
     */
    @TableField("views_number")
    private Integer viewsNumber;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/EncyclopedicKnowledgeUpvote.java
New file
@@ -0,0 +1,32 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/24 17:22
 */
@Data
@TableName("t_encyclopedic_knowledge_upvote")
public class EncyclopedicKnowledgeUpvote {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 知识百科id
     */
    @TableField("encyclopedic_knowledge_id")
    private Integer encyclopedicKnowledgeId;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Expense.java
New file
@@ -0,0 +1,123 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
 * <p>
 * 报销表
 * </p>
 *
 * @author stylefeng
 * @since 2017-12-05
 */
@TableName("sys_expense")
public class Expense extends Model<Expense> {
    private static final long serialVersionUID = 1L;
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 报销金额
     */
    private BigDecimal money;
    /**
     * 描述
     */
    private String desc;
    private Date createtime;
    /**
     * 状态: 1.待提交  2:待审核   3.审核通过
     */
    private Integer state;
    /**
     * 用户id
     */
    private Integer userid;
    /**
     * 流程定义id
     */
    private String processId;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public BigDecimal getMoney() {
        return money;
    }
    public void setMoney(BigDecimal money) {
        this.money = money;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Integer getState() {
        return state;
    }
    public void setState(Integer state) {
        this.state = state;
    }
    public Integer getUserid() {
        return userid;
    }
    public void setUserid(Integer userid) {
        this.userid = userid;
    }
    public String getProcessId() {
        return processId;
    }
    public void setProcessId(String processId) {
        this.processId = processId;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Expense{" +
            "id=" + id +
            ", money=" + money +
            ", desc=" + desc +
            ", createtime=" + createtime +
            ", state=" + state +
            ", userid=" + userid +
            ", processId=" + processId +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HouseResource.java
New file
@@ -0,0 +1,235 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.math.BigDecimal;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/8 10:57
 */
@Data
@TableName("t_house_resource")
public class HouseResource {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 编号
     */
    @TableField("code")
    private String code;
    /**
     * 房源类型(1=出租,2=卖房)
     */
    @TableField("data_type")
    private Integer dataType;
    /**
     * 房源户型
     */
    @TableField("house_model")
    private String houseModel;
    /**
     * 标题
     */
    @TableField("title")
    private String title;
    /**
     * 小区名字
     */
    @TableField("cell_name")
    private String cellName;
    /**
     * 楼层
     */
    @TableField("floor")
    private String floor;
    /**
     * 售卖日期
     */
    @TableField("sale_date")
    private Date saleDate;
    /**
     * 售卖金额
     */
    @TableField("sale_amount")
    private BigDecimal saleAmount;
    /**
     * 租期时长(0=不限,1=一年以下,2=一年以上)
     */
    @TableField("rental_duration")
    private Integer rentalDuration;
    /**
     * 房屋朝向
     */
    @TableField("building_orientation")
    private String buildingOrientation;
    /**
     * 房屋类型id
     */
    @TableField("house_type_id")
    private Integer houseTypeId;
    /**
     * 公司盘(0=否,1=是)
     */
    @TableField("firm_house")
    private Integer firmHouse;
    /**
     * 房源照片
     */
    @TableField("house_photo")
    private String housePhoto;
    /**
     * 房源视频
     */
    @TableField("house_video")
    private String houseVideo;
    /**
     * 是否有电梯(0=否,1=是)
     */
    @TableField("elevator")
    private Integer elevator;
    /**
     * 是否有晾晒区(0=否,1=是)
     */
    @TableField("drying_area")
    private Integer dryingArea;
    /**
     * 是否有花园(0=否,1=是)
     */
    @TableField("garden")
    private Integer garden;
    /**
     * 是否有车位(0=否,1=是)
     */
    @TableField("carport")
    private Integer carport;
    /**
     * 是否有平台(0=否,1=是)
     */
    @TableField("balcony")
    private Integer balcony;
    /**
     * 是否可养宠物(0=否,1=是)
     */
    @TableField("keep_pet")
    private Integer keepPet;
    /**
     * 房屋面积
     */
    @TableField("house_area")
    private String houseArea;
    /**
     * 市id
     */
    @TableField("city_id")
    private Integer cityId;
    /**
     * 区id
     */
    @TableField("district_id")
    private String districtId;
    /**
     * 房屋地址
     */
    @TableField("house_address")
    private String houseAddress;
    /**
     * 经度
     */
    @TableField("longitude")
    private String longitude;
    /**
     * 纬度
     */
    @TableField("latitude")
    private String latitude;
    /**
     * 更多介绍
     */
    @TableField("more_introduction")
    private String moreIntroduction;
    /**
     * 浏览次数
     */
    @TableField("views_number")
    private Integer viewsNumber;
    /**
     * 必看好房(0=否,1=是)
     */
    @TableField("good_house")
    private Integer goodHouse;
    /**
     * 微信二维码
     */
    @TableField("wechat_qr_code")
    private String wechatQRCode;
    /**
     * 电话号码
     */
    @TableField("phone")
    private String phone;
    /**
     * WatchApp
     */
    @TableField("watch_app")
    private String watchApp;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 删除标识(0=否,1=是)
     */
    @TableField("is_delete")
    private Integer isDelete;
    /**
     * 状态(0=下架,1=上架)
     */
    @TableField("status")
    private Integer status;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
    /**
     * 添加用户
     */
    @TableField("insert_user_id")
    private Integer insertUserId;
    /**
     * 审核人id
     */
    @TableField("auth_user_id")
    private Integer authAUserId;
    /**
     * 审核状态(1=待审核,2=已通过,3=已拒绝)
     */
    @TableField("auth_status")
    private Integer authStatus;
    /**
     * 审核时间
     */
    @TableField("auth_time")
    private Date authTime;
    /**
     * 修改时间
     */
    @TableField("update_time")
    private Date updateTime;
    /**
     * 修改人id
     */
    @TableField("update_user_id")
    private Integer updateUserId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HouseType.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 14:43
 */
@Data
@TableName("t_house_type")
public class HouseType {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 类型名称
     */
    @TableField("name")
    private String name;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HousingDemand.java
New file
@@ -0,0 +1,153 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 16:47
 */
@Data
@TableName("t_housing_demand")
public class HousingDemand {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 编号
     */
    @TableField("code")
    private String code;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 房源类型(1=租房,2=买房)
     */
    @TableField("data_type")
    private Integer dataType;
    /**
     * 标题
     */
    @TableField("title")
    private String title;
    /**
     * 房源区域
     */
    @TableField("district")
    private String district;
    /**
     * 价格区间
     */
    @TableField("sale_amount")
    private String saleAmount;
    /**
     * 房源户型
     */
    @TableField("house_model")
    private String houseModel;
    /**
     * 面积区间
     */
    @TableField("house_area")
    private String houseArea;
    /**
     * 租期
     */
    @TableField("rental_duration")
    private Integer rentalDuration;
    /**
     * 起租时间
     */
    @TableField("sale_date")
    private String saleDate;
    /**
     * 房屋类型id
     */
    @TableField("house_type_id")
    private String houseTypeId;
    /**
     * 所在楼层
     */
    @TableField("floor")
    private String floor;
    /**
     * 是否有电梯(0=否,1=是)
     */
    @TableField("elevator")
    private Integer elevator;
    /**
     * 是否有晾晒区(0=否,1=是)
     */
    @TableField("drying_area")
    private Integer dryingArea;
    /**
     * 是否有花园(0=否,1=是)
     */
    @TableField("garden")
    private Integer garden;
    /**
     * 是否有车位(0=否,1=是)
     */
    @TableField("carport")
    private Integer carport;
    /**
     * 是否有平台(0=否,1=是)
     */
    @TableField("balcony")
    private Integer balcony;
    /**
     * 是否可养宠物(0=否,1=是)
     */
    @TableField("keep_pet")
    private Integer keepPet;
    /**
     * 更多介绍
     */
    @TableField("more_introduction")
    private String moreIntroduction;
    /**
     * 浏览次数
     */
    @TableField("views_number")
    private Integer viewsNumber;
    /**
     * 删除标识(0=否,1=是)
     */
    @TableField("is_delete")
    private Integer isDelete;
    /**
     * 状态(0=下架,1=上架)
     */
    @TableField("status")
    private Integer status;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
    /**
     * 添加用户
     */
    @TableField("insert_user_id")
    private Integer insertUserId;
    /**
     * 修改时间
     */
    @TableField("update_time")
    private Date updateTime;
    /**
     * 修改人id
     */
    @TableField("update_user_id")
    private Integer updateUserId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/HousingDemandDistrict.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 9:27
 */
@Data
@TableName("t_housing_demand_district")
public class HousingDemandDistrict {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 求房源id
     */
    @TableField("housing_demand_id")
    private Integer housingDemandId;
    /**
     * 城市id
     */
    @TableField("city_id")
    private Integer cityId;
    /**
     * 区域id
     */
    @TableField("district_id")
    private Integer districtId;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/LoginLog.java
New file
@@ -0,0 +1,128 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 登录记录
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_login_log")
public class LoginLog extends Model<LoginLog> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 日志名称
     */
    private String logname;
    /**
     * 管理员id
     */
    private Integer userid;
    /**
     * 创建时间
     */
    private Date createtime;
    /**
     * 是否执行成功
     */
    private String succeed;
    /**
     * 具体消息
     */
    private String message;
    /**
     * 登录ip
     */
    private String ip;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLogname() {
        return logname;
    }
    public void setLogname(String logname) {
        this.logname = logname;
    }
    public Integer getUserid() {
        return userid;
    }
    public void setUserid(Integer userid) {
        this.userid = userid;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public String getSucceed() {
        return succeed;
    }
    public void setSucceed(String succeed) {
        this.succeed = succeed;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "LoginLog{" +
            "id=" + id +
            ", logname=" + logname +
            ", userid=" + userid +
            ", createtime=" + createtime +
            ", succeed=" + succeed +
            ", message=" + message +
            ", ip=" + ip +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Menu.java
New file
@@ -0,0 +1,208 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import org.hibernate.validator.constraints.NotBlank;
import java.io.Serializable;
/**
 * <p>
 * 菜单表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_menu")
public class Menu extends Model<Menu> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     * 菜单编号
     */
    private String code;
    /**
     * 菜单父编号
     */
    private String pcode;
    /**
     * 当前菜单的所有父菜单编号
     */
    private String pcodes;
    /**
     * 菜单名称
     */
    @NotBlank
    private String name;
    /**
     * 菜单图标
     */
    private String icon;
    /**
     * url地址
     */
    @NotBlank
    private String url;
    /**
     * 菜单排序号
     */
    private Integer num;
    /**
     * 菜单层级
     */
    private Integer levels;
    /**
     * 是否是菜单(1:是  0:不是)
     */
    private Integer ismenu;
    /**
     * 备注
     */
    private String tips;
    /**
     * 菜单状态 :  1:启用   0:不启用
     */
    private Integer status;
    /**
     * 是否打开:    1:打开   0:不打开
     */
    private Integer isopen;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getPcode() {
        return pcode;
    }
    public void setPcode(String pcode) {
        this.pcode = pcode;
    }
    public String getPcodes() {
        return pcodes;
    }
    public void setPcodes(String pcodes) {
        this.pcodes = pcodes;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getIcon() {
        return icon;
    }
    public void setIcon(String icon) {
        this.icon = icon;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    public Integer getLevels() {
        return levels;
    }
    public void setLevels(Integer levels) {
        this.levels = levels;
    }
    public Integer getIsmenu() {
        return ismenu;
    }
    public void setIsmenu(Integer ismenu) {
        this.ismenu = ismenu;
    }
    public String getTips() {
        return tips;
    }
    public void setTips(String tips) {
        this.tips = tips;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public Integer getIsopen() {
        return isopen;
    }
    public void setIsopen(Integer isopen) {
        this.isopen = isopen;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Menu{" +
                "id=" + id +
                ", code=" + code +
                ", pcode=" + pcode +
                ", pcodes=" + pcodes +
                ", name=" + name +
                ", icon=" + icon +
                ", url=" + url +
                ", num=" + num +
                ", levels=" + levels +
                ", ismenu=" + ismenu +
                ", tips=" + tips +
                ", status=" + status +
                ", isopen=" + isopen +
                "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Notice.java
New file
@@ -0,0 +1,115 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 通知表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_notice")
public class Notice extends Model<Notice> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 标题
     */
    private String title;
    /**
     * 类型
     */
    private Integer type;
    /**
     * 内容
     */
    private String content;
    /**
     * 创建时间
     */
    private Date createtime;
    /**
     * 创建人
     */
    private Integer creater;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Integer getType() {
        return type;
    }
    public void setType(Integer type) {
        this.type = type;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Integer getCreater() {
        return creater;
    }
    public void setCreater(Integer creater) {
        this.creater = creater;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Notice{" +
            "id=" + id +
            ", title=" + title +
            ", type=" + type +
            ", content=" + content +
            ", createtime=" + createtime +
            ", creater=" + creater +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/OperationLog.java
New file
@@ -0,0 +1,154 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 操作日志
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_operation_log")
public class OperationLog extends Model<OperationLog> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 日志类型
     */
    private String logtype;
    /**
     * 日志名称
     */
    private String logname;
    /**
     * 用户id
     */
    private Integer userid;
    /**
     * 类名称
     */
    private String classname;
    /**
     * 方法名称
     */
    private String method;
    /**
     * 创建时间
     */
    private Date createtime;
    /**
     * 是否成功
     */
    private String succeed;
    /**
     * 备注
     */
    private String message;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLogtype() {
        return logtype;
    }
    public void setLogtype(String logtype) {
        this.logtype = logtype;
    }
    public String getLogname() {
        return logname;
    }
    public void setLogname(String logname) {
        this.logname = logname;
    }
    public Integer getUserid() {
        return userid;
    }
    public void setUserid(Integer userid) {
        this.userid = userid;
    }
    public String getClassname() {
        return classname;
    }
    public void setClassname(String classname) {
        this.classname = classname;
    }
    public String getMethod() {
        return method;
    }
    public void setMethod(String method) {
        this.method = method;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public String getSucceed() {
        return succeed;
    }
    public void setSucceed(String succeed) {
        this.succeed = succeed;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "OperationLog{" +
            "id=" + id +
            ", logtype=" + logtype +
            ", logname=" + logname +
            ", userid=" + userid +
            ", classname=" + classname +
            ", method=" + method +
            ", createtime=" + createtime +
            ", succeed=" + succeed +
            ", message=" + message +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Region.java
New file
@@ -0,0 +1,53 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.List;
/**
* 行政区域数据
* @author pzb
* @Date 2022/2/9 10:00
*/
@Data
@TableName("t_region")
public class Region {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 城市名称
     */
    @TableField("name")
    @ApiModelProperty("名称")
    private String name;
    /**
     * 城市code
     */
    @TableField("code")
    @ApiModelProperty("编码")
    private String code;
    /**
     * 父级id
     */
    @TableField("parent_id")
    private Integer parentId;
    /**
     * 经度
     */
    @TableField("longitude")
    private String longitude;
    /**
     * 纬度
     */
    @TableField("latitude")
    private String latitude;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Relation.java
New file
@@ -0,0 +1,75 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
 * <p>
 * 角色和菜单关联表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_relation")
public class Relation extends Model<Relation> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 菜单id
     */
    private Long menuid;
    /**
     * 角色id
     */
    private Integer roleid;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Long getMenuid() {
        return menuid;
    }
    public void setMenuid(Long menuid) {
        this.menuid = menuid;
    }
    public Integer getRoleid() {
        return roleid;
    }
    public void setRoleid(Integer roleid) {
        this.roleid = roleid;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Relation{" +
                "id=" + id +
                ", menuid=" + menuid +
                ", roleid=" + roleid +
                "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/ReportHouseResource.java
New file
@@ -0,0 +1,42 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 15:26
 */
@Data
@TableName("t_report_house_resource")
public class ReportHouseResource {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 举报用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 房源id
     */
    @TableField("house_resource_id")
    private Integer houseResourceId;
    /**
     * 举报内容
     */
    @TableField("content")
    private String content;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/ReportHousingDemand.java
New file
@@ -0,0 +1,43 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:52
 */
@Data
@TableName("t_report_housing_demand")
public class ReportHousingDemand {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 举报用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 房源id
     */
    @TableField("housing_demand_id")
    private Integer housingDemandId;
    /**
     * 举报内容
     */
    @TableField("content")
    private String content;
    /**
     * 添加时间
     */
    @TableField("insert_time")
    private Date insertTime;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/Role.java
New file
@@ -0,0 +1,127 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
/**
 * <p>
 * 角色表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_role")
public class Role extends Model<Role> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 序号
     */
    private Integer num;
    /**
     * 父角色id
     */
    private Integer pid;
    /**
     * 角色名称
     */
    private String name;
    /**
     * 部门名称
     */
    private Integer deptid;
    /**
     * 提示
     */
    private String tips;
    /**
     * 保留字段(暂时没用)
     */
    private Integer version;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Integer getNum() {
        return num;
    }
    public void setNum(Integer num) {
        this.num = num;
    }
    public Integer getPid() {
        return pid;
    }
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getDeptid() {
        return deptid;
    }
    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }
    public String getTips() {
        return tips;
    }
    public void setTips(String tips) {
        this.tips = tips;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "Role{" +
            "id=" + id +
            ", num=" + num +
            ", pid=" + pid +
            ", name=" + name +
            ", deptid=" + deptid +
            ", tips=" + tips +
            ", version=" + version +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/SearchHistoryCondition.java
New file
@@ -0,0 +1,51 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 10:42
 */
@Data
@TableName("t_search_history_condition")
public class SearchHistoryCondition {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 用户id
     */
    @TableField("app_user_id")
    private Integer appUserId;
    /**
     * 区域code
     */
    @TableField("district")
    private String district;
    /**
     * 价格区间
     */
    @TableField("price")
    private String price;
    /**
     * 户型
     */
    @TableField("house_models")
    private String houseModels;
    /**
     * 是否有电梯(0=否,1=是)
     */
    @TableField("elevator")
    private Integer elevator;
    /**
     * 房屋类型id
     */
    @TableField("house_type_ids")
    private String houseTypeIds;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/SysDataType.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import lombok.Data;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:21
 */
@Data
@TableName("t_sys_data_type")
public class SysDataType {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;
    /**
     * 类型(1=知识百科)
     */
    @TableField("type")
    private Integer type;
    /**
     * 名称
     */
    @TableField("name")
    private String name;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/model/User.java
New file
@@ -0,0 +1,246 @@
package com.stylefeng.guns.modular.system.model;
import com.baomidou.mybatisplus.activerecord.Model;
import com.baomidou.mybatisplus.annotations.TableField;
import com.baomidou.mybatisplus.annotations.TableId;
import com.baomidou.mybatisplus.annotations.TableName;
import com.baomidou.mybatisplus.enums.IdType;
import java.io.Serializable;
import java.util.Date;
/**
 * <p>
 * 管理员表
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
@TableName("sys_user")
public class User extends Model<User> {
    private static final long serialVersionUID = 1L;
    /**
     * 主键id
     */
    @TableId(value="id", type= IdType.AUTO)
    private Integer id;
    /**
     * 头像
     */
    private String avatar;
    /**
     * 账号
     */
    private String account;
    /**
     * 密码
     */
    private String password;
    /**
     * md5密码盐
     */
    private String salt;
    /**
     * 名字
     */
    private String name;
    /**
     * 生日
     */
    private Date birthday;
    /**
     * 性别(1:男 2:女)
     */
    private Integer sex;
    /**
     * 电子邮件
     */
    private String email;
    /**
     * 电话
     */
    private String phone;
    /**
     * 角色id
     */
    private String roleid;
    /**
     * 部门id
     */
    private Integer deptid;
    /**
     * 状态(1:启用  2:冻结  3:删除)
     */
    private Integer status;
    /**
     * 创建时间
     */
    private Date createtime;
    /**
     * 保留字段
     */
    private Integer version;
    /**
     * 最后登录时间
     * @return
     */
    private Date updatePasswordTime;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAvatar() {
        return avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSalt() {
        return salt;
    }
    public void setSalt(String salt) {
        this.salt = salt;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getRoleid() {
        return roleid;
    }
    public void setRoleid(String roleid) {
        this.roleid = roleid;
    }
    public Integer getDeptid() {
        return deptid;
    }
    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
    public Date getUpdatePasswordTime() {
        return updatePasswordTime;
    }
    public void setUpdatePasswordTime(Date updatePasswordTime) {
        this.updatePasswordTime = updatePasswordTime;
    }
    @Override
    protected Serializable pkVal() {
        return this.id;
    }
    @Override
    public String toString() {
        return "User{" +
            "id=" + id +
            ", avatar=" + avatar +
            ", account=" + account +
            ", password=" + password +
            ", salt=" + salt +
            ", name=" + name +
            ", birthday=" + birthday +
            ", sex=" + sex +
            ", email=" + email +
            ", phone=" + phone +
            ", roleid=" + roleid +
            ", deptid=" + deptid +
            ", status=" + status +
            ", createtime=" + createtime +
            ", version=" + version +
            "}";
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IAppUserService.java
New file
@@ -0,0 +1,41 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.RegisterAccountReq;
import com.stylefeng.guns.modular.system.warpper.res.AppletLoginRes;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 11:07
 */
public interface IAppUserService extends IService<AppUser> {
    /**
     * 通过token获取用户信息
     * @return
     */
    AppUser getAppUser();
    /**
     * 小程序登录
     * @param jscode
     * @return
     */
    ResultUtil<AppletLoginRes> appletLogin(String jscode);
    /**
     * 小程序注册账号
     * @param req
     * @return
     */
    ResultUtil<AppletLoginRes> registerAccount(RegisterAccountReq req);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IBannerService.java
New file
@@ -0,0 +1,22 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.Banner;
import com.stylefeng.guns.modular.system.warpper.res.BannerRes;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 16:41
 */
public interface IBannerService extends IService<Banner> {
    /**
     * 获取banner
     * @param position
     * @return
     */
    List<BannerRes> getBanners(Integer position);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ICollectionHouseResourceService.java
New file
@@ -0,0 +1,19 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.CollectionHouseResource;
import com.stylefeng.guns.modular.system.util.ResultUtil;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 17:34
 */
public interface ICollectionHouseResourceService extends IService<CollectionHouseResource> {
    /**
     * 收藏/取消收藏操作
     * @param id
     */
    ResultUtil collectionHouseResource(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ICollectionHousingDemandService.java
New file
@@ -0,0 +1,20 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.CollectionHousingDemand;
import com.stylefeng.guns.modular.system.util.ResultUtil;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:47
 */
public interface ICollectionHousingDemandService extends IService<CollectionHousingDemand> {
    /**
     * 收藏/取消收藏房源操作
     * @param id
     * @return
     */
    ResultUtil collectionHousingDemand(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IDeptService.java
New file
@@ -0,0 +1,33 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Dept;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * 部门服务
 *
 * @author fengshuonan
 * @date 2017-04-27 17:00
 */
public interface IDeptService extends IService<Dept> {
    /**
     * 删除部门
     */
    void deleteDept(Integer deptId);
    /**
     * 获取ztree的节点列表
     */
    List<ZTreeNode> tree();
    /**
     * 获取所有部门列表
     */
    List<Map<String, Object>> list(@Param("condition") String condition);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IDictService.java
New file
@@ -0,0 +1,48 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.Dict;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * 字典服务
 *
 * @author fengshuonan
 * @date 2017-04-27 17:00
 */
public interface IDictService extends IService<Dict> {
    /**
     * 添加字典
     */
    void addDict(String dictCode,String dictName,String dictTips, String dictValues);
    /**
     * 编辑字典
     */
    void editDict(Integer dictId,String dictCode, String dictName,String dictTips, String dicts);
    /**
     * 删除字典
     */
    void delteDict(Integer dictId);
    /**
     * 根据编码获取词典列表
     */
    List<Dict> selectByCode(@Param("code") String code);
    /**
     * 根据父类编码获取词典列表
     */
    List<Dict> selectByParentCode(@Param("code") String code);
    /**
     * 查询字典列表
     */
    List<Map<String, Object>> list(@Param("condition") String conditiion);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IEncyclopedicKnowledgeService.java
New file
@@ -0,0 +1,40 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledge;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeRes;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:18
 */
public interface IEncyclopedicKnowledgeService extends IService<EncyclopedicKnowledge> {
    /**
     * 获取列表数据
     * @param typeId
     * @return
     */
    List<EncyclopedicKnowledgeRes> getEncyclopedicKnowledgeList(Integer typeId);
    /**
     * 获取详情
     * @param id
     * @return
     */
    EncyclopedicKnowledgeInfoRes getEncyclopedicKnowledgeInfo(Integer id);
    /**
     * 点赞/取消点赞操作
     * @param id
     * @return
     */
    ResultUtil upvoteEncyclopedicKnowledge(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IEncyclopedicKnowledgeUpvoteService.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledgeUpvote;
/**
 * @author zhibing.pu
 * @Date 2023/11/24 17:29
 */
public interface IEncyclopedicKnowledgeUpvoteService extends IService<EncyclopedicKnowledgeUpvote> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHouseResourceService.java
New file
@@ -0,0 +1,58 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.HouseResource;
import com.stylefeng.guns.modular.system.warpper.req.SearchHouseResourceReq;
import com.stylefeng.guns.modular.system.warpper.res.*;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/8 15:09
 */
public interface IHouseResourceService extends IService<HouseResource> {
    /**
     * 获取房源列表
     * @param req
     * @return
     */
    SearchHouseResourceRes searchHouseResource(SearchHouseResourceReq req);
    /**
     * 获取区域房源数量
     * @return
     */
    List<DistrictHouseResourceNumberRes> getDistrictHouseResourceNumber(Integer userType, Integer dataType);
    /**
     * 获取房源详情
     * @param id
     * @return
     */
    HouseResourceInfoRes getHouseResourceInfo(Integer id);
    /**
     * 获取附近房源
     * @param id
     * @return
     */
    List<SearchHouseResourceListRes> getNearbyHouseResource(Integer id);
    /**
     * 获取联系方式
     * @param id
     * @return
     */
    ContactInformationRes getContactInformation(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHouseTypeService.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.HouseType;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 14:45
 */
public interface IHouseTypeService extends IService<HouseType> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHousingDemandDistrictService.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.HousingDemandDistrict;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 9:49
 */
public interface IHousingDemandDistrictService extends IService<HousingDemandDistrict> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IHousingDemandService.java
New file
@@ -0,0 +1,58 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.HousingDemand;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.HousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.req.SearchHousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.res.ContactInformationRes;
import com.stylefeng.guns.modular.system.warpper.res.HousingDemandInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandRes;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 16:59
 */
public interface IHousingDemandService extends IService<HousingDemand> {
    /**
     * 添加房源需求
     * @param req
     */
    ResultUtil addHousingDemand(HousingDemandReq req);
    /**
     * 搜索求房源列表数据
     * @param req
     * @return
     */
    SearchHousingDemandRes searchHousingDemand(SearchHousingDemandReq req);
    /**
     * 获取求房源详情
     * @param id
     * @return
     */
    HousingDemandInfoRes housingDemandInfo(Integer id);
    /**
     * 获取联系方式
     * @param id
     * @return
     */
    ContactInformationRes getContactInformation(Integer id);
    /**
     * 获取剩余发布数量
     * @return
     */
    ResultUtil<Integer> getSurplusPushNumber();
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ILoginLogService.java
New file
@@ -0,0 +1,24 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.LoginLog;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 登录记录 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface ILoginLogService extends IService<LoginLog> {
    /**
     * 获取登录日志列表
     */
    List<Map<String, Object>> getLoginLogs(Page<LoginLog> page, String beginTime, String endTime, String logName, String orderByField, boolean asc);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IMenuService.java
New file
@@ -0,0 +1,94 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.core.node.MenuNode;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Menu;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * 菜单服务
 *
 * @author fengshuonan
 * @date 2017-05-05 22:19
 */
public interface IMenuService extends IService<Menu> {
    /**
     * 删除菜单
     *
     * @author stylefeng
     * @Date 2017/5/5 22:20
     */
    void delMenu(Long menuId);
    /**
     * 删除菜单包含所有子菜单
     *
     * @author stylefeng
     * @Date 2017/6/13 22:02
     */
    void delMenuContainSubMenus(Long menuId);
    /**
     * 根据条件查询菜单
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Map<String, Object>> selectMenus(@Param("condition") String condition, @Param("level") String level);
    /**
     * 根据条件查询菜单
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Long> getMenuIdsByRoleId(@Param("roleId") Integer roleId);
    /**
     * 获取菜单列表树
     *
     * @return
     * @date 2017年2月19日 下午1:33:51
     */
    List<ZTreeNode> menuTreeList();
    /**
     * 获取菜单列表树
     *
     * @return
     * @date 2017年2月19日 下午1:33:51
     */
    List<ZTreeNode> menuTreeListByMenuIds(List<Long> menuIds);
    /**
     * 删除menu关联的relation
     *
     * @param menuId
     * @return
     * @date 2017年2月19日 下午4:10:59
     */
    int deleteRelationByMenu(Long menuId);
    /**
     * 获取资源url通过角色id
     *
     * @param roleId
     * @return
     * @date 2017年2月19日 下午7:12:38
     */
    List<String> getResUrlsByRoleId(Integer roleId);
    /**
     * 根据角色获取菜单
     *
     * @param roleIds
     * @return
     * @date 2017年2月19日 下午10:35:40
     */
    List<MenuNode> getMenusByRoleIds(List<Integer> roleIds);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/INoticeService.java
New file
@@ -0,0 +1,23 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.Notice;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 通知表 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface INoticeService extends IService<Notice> {
    /**
     * 获取通知列表
     */
    List<Map<String, Object>> list(String condition);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IOperationLogService.java
New file
@@ -0,0 +1,24 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.OperationLog;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 操作日志 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface IOperationLogService extends IService<OperationLog> {
    /**
     * 获取操作日志列表
     */
    List<Map<String, Object>> getOperationLogs(Page<OperationLog> page, String beginTime, String endTime, String logName, String s, String orderByField, boolean asc);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRegionService.java
New file
@@ -0,0 +1,17 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.Region;
import com.stylefeng.guns.modular.system.warpper.res.DistrictRes;
import java.util.List;
public interface IRegionService extends IService<Region> {
    /**
     * 获取行政区划数据
     * @param parentId
     * @return
     */
    List<DistrictRes> getDistrict(Integer parentId);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRelationService.java
New file
@@ -0,0 +1,16 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.Relation;
/**
 * <p>
 * 角色和菜单关联表 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface IRelationService extends IService<Relation> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReportHouseResourceService.java
New file
@@ -0,0 +1,21 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.ReportHouseResource;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.ReportHouseResourceReq;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 15:30
 */
public interface IReportHouseResourceService extends IService<ReportHouseResource> {
    /**
     * 添加举报内容
     * @param req
     */
    ResultUtil addReportHouseResource(ReportHouseResourceReq req);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IReportHousingDemandService.java
New file
@@ -0,0 +1,20 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.ReportHousingDemand;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.ReportHousingDemandReq;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:55
 */
public interface IReportHousingDemandService extends IService<ReportHousingDemand> {
    /**
     * 添加举报求房源记录
     * @param req
     */
    ResultUtil addReportHousingDemand(ReportHousingDemandReq req);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IRoleService.java
New file
@@ -0,0 +1,68 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.model.Role;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * 角色相关业务
 *
 * @author fengshuonan
 * @Date 2017年1月10日 下午9:11:57
 */
public interface IRoleService extends IService<Role> {
    /**
     * 设置某个角色的权限
     *
     * @param roleId 角色id
     * @param ids    权限的id
     * @date 2017年2月13日 下午8:26:53
     */
    void setAuthority(Integer roleId, String ids);
    /**
     * 删除角色
     *
     * @author stylefeng
     * @Date 2017/5/5 22:24
     */
    void delRoleById(Integer roleId);
    /**
     * 根据条件查询角色列表
     *
     * @return
     * @date 2017年2月12日 下午9:14:34
     */
    List<Map<String, Object>> selectRoles(@Param("condition") String condition);
    /**
     * 删除某个角色的所有权限
     *
     * @param roleId 角色id
     * @return
     * @date 2017年2月13日 下午7:57:51
     */
    int deleteRolesById(@Param("roleId") Integer roleId);
    /**
     * 获取角色列表树
     *
     * @return
     * @date 2017年2月18日 上午10:32:04
     */
    List<ZTreeNode> roleTreeList();
    /**
     * 获取角色列表树
     *
     * @return
     * @date 2017年2月18日 上午10:32:04
     */
    List<ZTreeNode> roleTreeListByRoleId(String[] roleId);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ISearchHistoryConditionService.java
New file
@@ -0,0 +1,11 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.SearchHistoryCondition;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 11:01
 */
public interface ISearchHistoryConditionService extends IService<SearchHistoryCondition> {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/ISysDataTypeService.java
New file
@@ -0,0 +1,20 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.modular.system.model.SysDataType;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:35
 */
public interface ISysDataTypeService extends IService<SysDataType> {
    /**
     * 获取类别数据
     * @param type
     * @return
     */
    List<SysDataType> getSysDataType(Integer type);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/IUserService.java
New file
@@ -0,0 +1,48 @@
package com.stylefeng.guns.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.stylefeng.guns.core.datascope.DataScope;
import com.stylefeng.guns.modular.system.model.User;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 管理员表 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface IUserService extends IService<User> {
    /**
     * 修改用户状态
     */
    int setStatus(@Param("userId") Integer userId, @Param("status") int status);
    /**
     * 修改密码
     */
    int changePwd(@Param("userId") Integer userId, @Param("pwd") String pwd);
    /**
     * 根据条件查询用户列表
     */
    List<Map<String, Object>> selectUsers(@Param("dataScope") DataScope dataScope, @Param("name") String name, @Param("beginTime") String beginTime, @Param("endTime") String endTime, @Param("deptid") Integer deptid);
    /**
     * 设置用户的角色
     */
    int setRoles(@Param("userId") Integer userId, @Param("roleIds") String roleIds);
    /**
     * 通过账号获取用户
     */
    User getByAccount(@Param("account") String account);
    Map<String,Object> getSysUserDetails(Integer id);
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/AppUserServiceImpl.java
New file
@@ -0,0 +1,192 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.util.JwtTokenUtil;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.AppUserMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.util.RedisUtil;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.util.UUIDUtil;
import com.stylefeng.guns.modular.system.util.weChat.WXCore;
import com.stylefeng.guns.modular.system.util.weChat.WeChatUtil;
import com.stylefeng.guns.modular.system.warpper.req.RegisterAccountReq;
import com.stylefeng.guns.modular.system.warpper.res.AppletLoginRes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 11:07
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
    @Autowired
    private WeChatUtil weChatUtil;
    @Autowired
    private RedisUtil redisUtil;
    /**
     * 通过token获取用户信息
     * @return
     */
    @Override
    public AppUser getAppUser() {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String authorization = request.getHeader("Authorization");
        if(ToolUtil.isNotEmpty(authorization) && authorization.contains("Bearer")){
            String token = authorization.substring(7);
            //通过token获取用户id
            Integer appUserId = getAppUserIdFromToken(token);
            return this.selectById(appUserId);
        }
        return null;
    }
    /**
     * 小程序登录
     * @param jscode
     * @return
     */
    @Override
    public ResultUtil<AppletLoginRes> appletLogin(String jscode) {
        try {
            //调用微信获取用户小程序openid
            Map<String, Object> map = weChatUtil.code2Session(jscode);
            if(null == map){
                return ResultUtil.error("获取微信身份信息失败");
            }
            String openid = map.get("openid").toString();
            AppUser appUser = this.selectOne(new EntityWrapper<AppUser>()
                    .eq("wechat_openid", openid)
                    .eq("audit_status", 2)
                    .eq("status", 1));
            AppletLoginRes appletLoginRes = new AppletLoginRes();
            if(null != appUser){
                String token = JwtTokenUtil.generateToken(appUser.getPhone());
                appletLoginRes.setToken(token);
            }
            return ResultUtil.success(appletLoginRes);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 小程序注册账号
     * @param req
     * @return
     */
    @Override
    public ResultUtil<AppletLoginRes> registerAccount(RegisterAccountReq req) {
        try {
            //调用微信获取用户小程序openid
            Map<String, Object> map = weChatUtil.code2Session(req.getJscode());
            if(null == map){
                return ResultUtil.error("获取微信身份信息失败");
            }
            String openid = map.get("openid").toString();
            AppUser appUser = this.selectOne(new EntityWrapper<AppUser>()
                    .eq("wechat_openid", openid)
                    .eq("audit_status", 2)
                    .eq("status", 1));
            AppletLoginRes appletLoginRes = new AppletLoginRes();
            if(null == appUser){
                String sessionKey = map.get("sessionKey").toString();
                //解密手机号
                String phone = WXCore.decrypt(req.getEncryptedPhoneData(), sessionKey, req.getPhone_iv());
                appUser = this.selectOne(new EntityWrapper<AppUser>()
                        .eq("phone", phone)
                        .eq("audit_status", 2)
                        .eq("status", 1));
                if(null == appUser){
                    //注册新账号
                    addNewAppUser(openid, phone);
                }else{
                    appUser.setWechatOpenid(openid);
                    this.updateById(appUser);
                }
            }
            //生成token
            String token = JwtTokenUtil.generateToken(appUser.getPhone());
            appletLoginRes.setToken(token);
            //存入缓存中
            addTokenToRedis(token, appUser.getId());
            return ResultUtil.success(appletLoginRes);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 添加新用户到数据库
     * @param openid    微信openid
     * @param phone     手机号
     */
    private void addNewAppUser(String openid, String phone){
        AppUser appUser = new AppUser();
        appUser.setCode(UUIDUtil.getNumberRandom(16));
        appUser.setUserType(1);
        appUser.setPhone(phone);
        appUser.setWechatOpenid(openid);
        appUser.setAuditStatus(2);
        appUser.setStatus(1);
        appUser.setInsertTime(new Date());
        this.insert(appUser);
    }
    /**
     * 将用户标识存入缓存中用于后期接口的身份校验
     * @param token
     * @param id
     */
    private void addTokenToRedis(String token, Integer id){
        String key = token;
        int length = token.length();
        if(length > 16){
            key = token.substring(4, 12);
        }
        //30天有效期
        redisUtil.setStrValue(key, id.toString(), 2592000);
    }
    /**
     * 通过token获取用户id
     * @param token
     * @return
     */
    private Integer getAppUserIdFromToken(String token){
        String key = token;
        int length = token.length();
        if(length > 16){
            key = token.substring(4, 12);
        }
        String value = redisUtil.getValue(key);
        if(ToolUtil.isEmpty(value)){
            return 0;
        }
        return Integer.valueOf(value);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/BannerServiceImpl.java
New file
@@ -0,0 +1,29 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.BannerMapper;
import com.stylefeng.guns.modular.system.model.Banner;
import com.stylefeng.guns.modular.system.service.IBannerService;
import com.stylefeng.guns.modular.system.warpper.res.BannerRes;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/7 16:41
 */
@Service
public class BannerServiceImpl extends ServiceImpl<BannerMapper, Banner> implements IBannerService {
    /**
     * 获取banner
     * @param position
     * @return
     */
    @Override
    public List<BannerRes> getBanners(Integer position) {
        return this.baseMapper.getBanners(position);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/CollectionHouseResourceServiceImpl.java
New file
@@ -0,0 +1,49 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.CollectionHouseResourceMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.model.CollectionHouseResource;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.service.ICollectionHouseResourceService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 17:34
 */
@Service
public class CollectionHouseResourceServiceImpl extends ServiceImpl<CollectionHouseResourceMapper, CollectionHouseResource> implements ICollectionHouseResourceService {
    @Autowired
    private IAppUserService appUserService;
    /**
     * 收藏/取消收藏房源操作
     * @param id
     * @return
     */
    @Override
    public ResultUtil collectionHouseResource(Integer id) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        CollectionHouseResource collectionHouseResource = this.selectOne(new EntityWrapper<CollectionHouseResource>()
                .eq("app_user_id", appUser.getId())
                .eq("house_resource_id", id));
        if(null == collectionHouseResource){
            collectionHouseResource = new CollectionHouseResource();
            collectionHouseResource.setAppUserId(appUser.getId());
            collectionHouseResource.setHouseResourceId(id);
            this.insert(collectionHouseResource);
        }else{
            this.deleteById(collectionHouseResource.getId());
        }
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/CollectionHousingDemandServiceImpl.java
New file
@@ -0,0 +1,50 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.CollectionHousingDemandMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.model.CollectionHousingDemand;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.service.ICollectionHousingDemandService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:48
 */
@Service
public class CollectionHousingDemandServiceImpl extends ServiceImpl<CollectionHousingDemandMapper, CollectionHousingDemand> implements ICollectionHousingDemandService {
    @Autowired
    private IAppUserService appUserService;
    /**
     * 收藏/取消收藏房源操作
     * @param id
     * @return
     */
    @Override
    public ResultUtil collectionHousingDemand(Integer id) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        CollectionHousingDemand collectionHouseResource = this.selectOne(new EntityWrapper<CollectionHousingDemand>()
                .eq("app_user_id", appUser.getId())
                .eq("housing_demand_id", id));
        if(null == collectionHouseResource){
            collectionHouseResource = new CollectionHousingDemand();
            collectionHouseResource.setAppUserId(appUser.getId());
            collectionHouseResource.setHousingDemandId(id);
            this.insert(collectionHouseResource);
        }else{
            this.deleteById(collectionHouseResource.getId());
        }
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DeptServiceImpl.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.dao.DeptMapper;
import com.stylefeng.guns.modular.system.model.Dept;
import com.stylefeng.guns.modular.system.service.IDeptService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
@Transactional
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {
    @Resource
    private DeptMapper deptMapper;
    @Override
    public void deleteDept(Integer deptId) {
        Dept dept = deptMapper.selectById(deptId);
        Wrapper<Dept> wrapper = new EntityWrapper<>();
        wrapper = wrapper.like("pids", "%[" + dept.getId() + "]%");
        List<Dept> subDepts = deptMapper.selectList(wrapper);
        for (Dept temp : subDepts) {
            temp.deleteById();
        }
        dept.deleteById();
    }
    @Override
    public List<ZTreeNode> tree() {
        return this.baseMapper.tree();
    }
    @Override
    public List<Map<String, Object>> list(String condition) {
        return this.baseMapper.list(condition);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/DictServiceImpl.java
New file
@@ -0,0 +1,101 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.common.exception.BizExceptionEnum;
import com.stylefeng.guns.core.exception.GunsException;
import com.stylefeng.guns.modular.system.dao.DictMapper;
import com.stylefeng.guns.modular.system.model.Dict;
import com.stylefeng.guns.modular.system.service.IDictService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import static com.stylefeng.guns.core.common.constant.factory.MutiStrFactory.*;
@Service
@Transactional
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements IDictService {
    @Resource
    private DictMapper dictMapper;
    @Override
    public void addDict(String dictCode,String dictName,String dictTips, String dictValues) {
        //判断有没有该字典
        List<Dict> dicts = dictMapper.selectList(new EntityWrapper<Dict>().eq("code", dictCode).and().eq("pid", 0));
        if (dicts != null && dicts.size() > 0) {
            throw new GunsException(BizExceptionEnum.DICT_EXISTED);
        }
        //解析dictValues
        List<Map<String, String>> items = parseKeyValue(dictValues);
        //添加字典
        Dict dict = new Dict();
        dict.setName(dictName);
        dict.setCode(dictCode);
        dict.setTips(dictTips);
        dict.setNum(0);
        dict.setPid(0);
        this.dictMapper.insert(dict);
        //添加字典条目
        for (Map<String, String> item : items) {
            String code = item.get(MUTI_STR_CODE);
            String name = item.get(MUTI_STR_NAME);
            String num = item.get(MUTI_STR_NUM);
            Dict itemDict = new Dict();
            itemDict.setPid(dict.getId());
            itemDict.setCode(code);
            itemDict.setName(name);
            try {
                itemDict.setNum(Integer.valueOf(num));
            } catch (NumberFormatException e) {
                throw new GunsException(BizExceptionEnum.DICT_MUST_BE_NUMBER);
            }
            this.dictMapper.insert(itemDict);
        }
    }
    @Override
    public void editDict(Integer dictId,String dictCode, String dictName,String dictTips, String dicts) {
        //删除之前的字典
        this.delteDict(dictId);
        //重新添加新的字典
        this.addDict(dictCode,dictName,dictTips, dicts);
    }
    @Override
    public void delteDict(Integer dictId) {
        //删除这个字典的子词典
        Wrapper<Dict> dictEntityWrapper = new EntityWrapper<>();
        dictEntityWrapper = dictEntityWrapper.eq("pid", dictId);
        dictMapper.delete(dictEntityWrapper);
        //删除这个词典
        dictMapper.deleteById(dictId);
    }
    @Override
    public List<Dict> selectByCode(String code) {
        return this.baseMapper.selectByCode(code);
    }
    @Override
    public List<Dict> selectByParentCode(String code) {
        return this.baseMapper.selectByParentCode(code);
    }
    @Override
    public List<Map<String, Object>> list(String conditiion) {
        return this.baseMapper.list(conditiion);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/EncyclopedicKnowledgeServiceImpl.java
New file
@@ -0,0 +1,101 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.EncyclopedicKnowledgeMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledge;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledgeUpvote;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.service.IEncyclopedicKnowledgeService;
import com.stylefeng.guns.modular.system.service.IEncyclopedicKnowledgeUpvoteService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.EncyclopedicKnowledgeRes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:19
 */
@Service
public class EncyclopedicKnowledgeServiceImpl extends ServiceImpl<EncyclopedicKnowledgeMapper, EncyclopedicKnowledge> implements IEncyclopedicKnowledgeService {
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IEncyclopedicKnowledgeUpvoteService encyclopedicKnowledgeUpvoteService;
    /**
     * 获取列表数据
     * @param typeId
     * @return
     */
    @Override
    public List<EncyclopedicKnowledgeRes> getEncyclopedicKnowledgeList(Integer typeId) {
        return this.baseMapper.getEncyclopedicKnowledgeList(typeId);
    }
    /**
     * 获取详情
     * @param id
     * @return
     */
    @Override
    public EncyclopedicKnowledgeInfoRes getEncyclopedicKnowledgeInfo(Integer id) {
        EncyclopedicKnowledge encyclopedicKnowledge = this.selectById(id);
        EncyclopedicKnowledgeInfoRes res = new EncyclopedicKnowledgeInfoRes();
        res.setId(id);
        res.setTitle(encyclopedicKnowledge.getTitle());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        res.setInsertTime(sdf.format(encyclopedicKnowledge.getInsertTime()));
        res.setContent(encyclopedicKnowledge.getContent());
        res.setViewsNumber(encyclopedicKnowledge.getViewsNumber());
        res.setUpvote(0);
        int count = encyclopedicKnowledgeUpvoteService.selectCount(new EntityWrapper<EncyclopedicKnowledgeUpvote>()
                .eq("encyclopedic_knowledge_id", id));
        res.setUpvoteNumber(count);
        AppUser appUser = appUserService.getAppUser();
        if(null != appUser){
            EncyclopedicKnowledgeUpvote encyclopedicKnowledgeUpvote = encyclopedicKnowledgeUpvoteService.selectOne(new EntityWrapper<EncyclopedicKnowledgeUpvote>()
                    .eq("encyclopedic_knowledge_id", id).eq("app_user_id", appUser.getId()));
            res.setUpvote(null == encyclopedicKnowledgeUpvote ? 0 : 1);
        }
        encyclopedicKnowledge.setViewsNumber(encyclopedicKnowledge.getViewsNumber() + 1);
        this.updateById(encyclopedicKnowledge);
        return res;
    }
    /**
     * 点赞/取消点赞操作
     * @param id
     * @return
     */
    @Override
    public ResultUtil upvoteEncyclopedicKnowledge(Integer id) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        EncyclopedicKnowledgeUpvote encyclopedicKnowledgeUpvote = encyclopedicKnowledgeUpvoteService.selectOne(new EntityWrapper<EncyclopedicKnowledgeUpvote>()
                .eq("encyclopedic_knowledge_id", id).eq("app_user_id", appUser.getId()));
        if(null == encyclopedicKnowledgeUpvote){
            encyclopedicKnowledgeUpvote = new EncyclopedicKnowledgeUpvote();
            encyclopedicKnowledgeUpvote.setEncyclopedicKnowledgeId(id);
            encyclopedicKnowledgeUpvote.setAppUserId(appUser.getId());
            encyclopedicKnowledgeUpvoteService.insert(encyclopedicKnowledgeUpvote);
        }else{
            encyclopedicKnowledgeUpvoteService.deleteById(encyclopedicKnowledgeUpvote.getId());
        }
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/EncyclopedicKnowledgeUpvoteServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.EncyclopedicKnowledgeUpvoteMapper;
import com.stylefeng.guns.modular.system.model.EncyclopedicKnowledgeUpvote;
import com.stylefeng.guns.modular.system.service.IEncyclopedicKnowledgeUpvoteService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/24 17:29
 */
@Service
public class EncyclopedicKnowledgeUpvoteServiceImpl extends ServiceImpl<EncyclopedicKnowledgeUpvoteMapper, EncyclopedicKnowledgeUpvote> implements IEncyclopedicKnowledgeUpvoteService {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HouseResourceService.java
New file
@@ -0,0 +1,300 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.HouseResourceMapper;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.system.service.*;
import com.stylefeng.guns.modular.system.warpper.PointLocation;
import com.stylefeng.guns.modular.system.warpper.req.SearchHouseResourceReq;
import com.stylefeng.guns.modular.system.warpper.res.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.geo.Point;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
 * @author zhibing.pu
 * @Date 2023/11/8 15:10
 */
@Service
public class HouseResourceService extends ServiceImpl<HouseResourceMapper, HouseResource> implements IHouseResourceService {
    @Autowired
    private ISearchHistoryConditionService searchHistoryConditionService;
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IRegionService regionService;
    @Autowired
    private IHouseTypeService houseTypeService;
    @Autowired
    private ICollectionHouseResourceService collectionHouseResourceService;
    @Resource
    private MongoTemplate mongoTemplate;
    /**
     * 获取房源列表
     * @param req
     * @return
     */
    @Override
    public SearchHouseResourceRes searchHouseResource(SearchHouseResourceReq req) {
        req.setPageNum((req.getPageNum() - 1) * req.getPageSize());
        //租房处理推荐和记录历史搜索数据
        if(req.getType() == 1){
            fillSearchHistory(req);
        }
        //区域
        List<Integer> districtIds = null;
        List<Integer> cityIds = null;
        if(StringUtils.hasLength(req.getDistrict())){
            cityIds = new ArrayList<>();
            districtIds = new ArrayList<>();
            JSONArray jsonArray = JSON.parseArray(req.getDistrict());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Integer cityId = jsonObject.getInteger("cityId");
                Integer districtId = jsonObject.getInteger("districtId");
                //不限区域
                if(0 == districtId || null == districtId){
                    List<Region> regions = regionService.selectList(new EntityWrapper<Region>().eq("parent_id", cityId));
                    districtIds.addAll(regions.stream().map(Region::getId).collect(Collectors.toList()));
                }
                cityIds.add(cityId);
                districtIds.add(districtId);
            }
        }
        //价格范围
        Double saleAmountStart = null;
        Double saleAmountEnd = null;
        if(StringUtils.hasLength(req.getSaleAmount())){
            String[] split = req.getSaleAmount().split("-");
            saleAmountStart = Double.valueOf(split[0]);
            saleAmountEnd = Double.valueOf(split[1]);
        }
        //户型
        List<String> houseModels = null;
        if(StringUtils.hasLength(req.getHouseModel())){
            String[] split = req.getHouseModel().split(",");
            houseModels = Arrays.asList(split);
        }
        //房型
        List<Integer> houseTypeIds = null;
        if(StringUtils.hasLength(req.getHouseTypeId())){
            houseTypeIds = new ArrayList<>();
            String[] split = req.getHouseTypeId().split(",");
            for (String s : split) {
                houseTypeIds.add(Integer.valueOf(s));
            }
        }
        SearchHouseResourceRes searchHouseResource = new SearchHouseResourceRes();
        List<SearchHouseResourceListRes> searchHouseResourceListRes = this.baseMapper.searchHouseResource(req, cityIds, districtIds, saleAmountStart, saleAmountEnd, houseModels, houseTypeIds);
        searchHouseResource.setList(searchHouseResourceListRes);
        Integer integer = this.baseMapper.searchHouseResourceCount(req, cityIds, districtIds, saleAmountStart, saleAmountEnd, houseModels, houseTypeIds);
        searchHouseResource.setTotal(integer);
        return searchHouseResource;
    }
    /**
     * 填装历史搜索记录和修改历史搜索记录
     * @param req
     */
    private void fillSearchHistory(SearchHouseResourceReq req){
        AppUser appUser = appUserService.getAppUser();
        if(null != appUser){
            //获取历史搜索数据
            SearchHistoryCondition searchHistoryCondition = searchHistoryConditionService.selectOne(new EntityWrapper<SearchHistoryCondition>().eq("app_user_id", appUser.getId()));
            if(null == searchHistoryCondition){
                //没有历史记录,将现有记录添加进去
                searchHistoryCondition = new SearchHistoryCondition();
                searchHistoryCondition.setAppUserId(appUser.getId());
                searchHistoryCondition.setDistrict(req.getDistrict());
                searchHistoryCondition.setPrice(req.getSaleAmount());
                searchHistoryCondition.setHouseModels(req.getHouseModel());
                searchHistoryCondition.setElevator(req.getElevator());
                searchHistoryCondition.setHouseTypeIds(req.getHouseTypeId());
                searchHistoryConditionService.insert(searchHistoryCondition);
            }else{
                //没有进行搜索的情况,将历史记录填充进搜素条件。有搜索条件则不填充,然后更新历史搜索条件
                if(ToolUtil.isEmpty(req.getDistrict()) && ToolUtil.isEmpty(req.getSaleAmount()) &&
                        ToolUtil.isEmpty(req.getHouseModel()) && ToolUtil.isEmpty(req.getElevator()) &&
                        ToolUtil.isEmpty(req.getHouseTypeId())){
                    req.setDistrict(searchHistoryCondition.getDistrict());
                    req.setSaleAmount(searchHistoryCondition.getPrice());
                    req.setHouseModel(searchHistoryCondition.getHouseModels());
                    req.setElevator(searchHistoryCondition.getElevator());
                    req.setHouseTypeId(searchHistoryCondition.getHouseTypeIds());
                }else{
                    //更新历史搜索记录
                    searchHistoryCondition.setDistrict(req.getDistrict());
                    searchHistoryCondition.setPrice(req.getSaleAmount());
                    searchHistoryCondition.setHouseModels(req.getHouseModel());
                    searchHistoryCondition.setElevator(req.getElevator());
                    searchHistoryCondition.setHouseTypeIds(req.getHouseTypeId());
                    searchHistoryConditionService.updateAllColumnById(searchHistoryCondition);
                }
            }
        }
    }
    /**
     * 获取区域房源数量
     * @return
     */
    @Override
    public List<DistrictHouseResourceNumberRes> getDistrictHouseResourceNumber(Integer userType, Integer dataType) {
        List<DistrictHouseResourceNumberRes> districtHouseResourceNumber = this.baseMapper.getDistrictHouseResourceNumber(userType, dataType);
        return districtHouseResourceNumber;
    }
    /**
     * 获取房源详情
     * @param id
     * @return
     */
    @Override
    public HouseResourceInfoRes getHouseResourceInfo(Integer id) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        AppUser appUser = appUserService.getAppUser();
        HouseResource houseResource = this.selectById(id);
        HouseResourceInfoRes houseResourceInfoRes = new HouseResourceInfoRes();
        houseResourceInfoRes.setId(id);
        houseResourceInfoRes.setTitle(houseResource.getTitle());
        houseResourceInfoRes.setSaleAmount(houseResource.getSaleAmount());
        houseResourceInfoRes.setHouseModel(houseResource.getHouseModel());
        houseResourceInfoRes.setRentalDuration(houseResource.getRentalDuration());
        houseResourceInfoRes.setSaleDate(sdf.format(houseResource.getSaleDate()));
        houseResourceInfoRes.setHousePhoto(houseResource.getHousePhoto());
        HouseType houseType = houseTypeService.selectById(houseResource.getHouseTypeId());
        houseResourceInfoRes.setHouseType(houseType.getName());
        houseResourceInfoRes.setFloor(houseResource.getFloor());
        houseResourceInfoRes.setElevator(houseResource.getElevator());
        houseResourceInfoRes.setDryingArea(houseResource.getDryingArea());
        houseResourceInfoRes.setHouseArea(houseResource.getHouseArea());
        houseResourceInfoRes.setKeepPet(houseResource.getKeepPet());
        Region region = regionService.selectById(houseResource.getDistrictId());
        Region region1 = regionService.selectById(houseResource.getCityId());
        houseResourceInfoRes.setAddress(region1.getName() + " > " + region.getName() + "/" + houseResource.getHouseAddress());
        houseResourceInfoRes.setLongitude(houseResource.getLongitude());
        houseResourceInfoRes.setLatitude(houseResource.getLatitude());
        houseResourceInfoRes.setMoreIntroduction(houseResource.getMoreIntroduction());
        houseResourceInfoRes.setViewsNumber(houseResource.getViewsNumber());
        AppUser appUser1 = appUserService.selectById(houseResource.getAppUserId());
        houseResourceInfoRes.setProfilePhoto(appUser1.getProfilePhoto());
        houseResourceInfoRes.setNickname(appUser1.getNickname());
        houseResourceInfoRes.setUserType(appUser1.getUserType());
        houseResourceInfoRes.setInsertTime(sdf.format(houseResource.getInsertTime()));
        houseResourceInfoRes.setUpdateTime(sdf.format(houseResource.getUpdateTime()));
        houseResourceInfoRes.setCode(houseResource.getCode());
        int collectionTimes = collectionHouseResourceService.selectCount(new EntityWrapper<CollectionHouseResource>().eq("house_resource_id", id));
        houseResourceInfoRes.setCollectionTimes(collectionTimes);
        houseResourceInfoRes.setCollection(0);
        if(null != appUser){
            int collection = collectionHouseResourceService.selectCount(new EntityWrapper<CollectionHouseResource>().eq("house_resource_id", id).eq("app_user_id", appUser.getId()));
            houseResourceInfoRes.setCollection(0 == collection ? 0 : 1);
        }
        //添加访问次数记录
        addViewsNumber(houseResource);
        return houseResourceInfoRes;
    }
    /**
     * 添加访问次数记录
     * @param houseResource
     */
    private void addViewsNumber(HouseResource houseResource){
        houseResource.setViewsNumber((null == houseResource.getViewsNumber() ? 0 : houseResource.getViewsNumber()) + 1);
        this.updateById(houseResource);
    }
    /**
     * 获取附近房源数据
     * @param id
     * @return
     */
    @Override
    public List<SearchHouseResourceListRes> getNearbyHouseResource(Integer id) {
        HouseResource houseResource = this.selectById(id);
        //获取中心半径5KM范围内的房源数据
        Double x = Double.valueOf(houseResource.getLongitude());
        Double y = Double.valueOf(houseResource.getLatitude());
        Point point = new Point(x, y);
        Circle circle = new Circle(point, new Distance(5, Metrics.KILOMETERS));
        Query query = Query.query(Criteria.where("geoJsonPoint").withinSphere(circle));
        List<PointLocation> pointLocations = mongoTemplate.find(query, PointLocation.class);
        List<Integer> ids = pointLocations.stream().map(PointLocation::getHouseId).collect(Collectors.toList());
        List<HouseResource> houseResources = this.selectBatchIds(ids);
        List<SearchHouseResourceListRes> list = new ArrayList<>();
        //遍历解析出返回数据
        for (HouseResource resource : houseResources) {
            SearchHouseResourceListRes searchHouseResourceListRes = new SearchHouseResourceListRes();
            searchHouseResourceListRes.setId(resource.getId());
            AppUser appUser = appUserService.selectById(resource.getAppUserId());
            searchHouseResourceListRes.setHouseResource(appUser.getUserType());
            searchHouseResourceListRes.setImgUrl(resource.getHousePhoto().split(",")[0]);
            searchHouseResourceListRes.setTitle(resource.getTitle());
            searchHouseResourceListRes.setHouseArea(resource.getHouseArea());
            searchHouseResourceListRes.setHouseModel(resource.getHouseModel());
            Region region = regionService.selectById(houseResource.getDistrictId());
            Region region1 = regionService.selectById(houseResource.getCityId());
            searchHouseResourceListRes.setAddress(region1.getName() + " > " + region.getName() + "/" + houseResource.getHouseAddress());
            searchHouseResourceListRes.setSaleAmount(resource.getSaleAmount().doubleValue());
            searchHouseResourceListRes.setElevator(resource.getElevator());
            searchHouseResourceListRes.setDryingArea(resource.getDryingArea());
            searchHouseResourceListRes.setGarden(resource.getGarden());
            searchHouseResourceListRes.setCarport(resource.getCarport());
            searchHouseResourceListRes.setBalcony(resource.getBalcony());
            searchHouseResourceListRes.setKeepPet(resource.getKeepPet());
            list.add(searchHouseResourceListRes);
        }
        return list;
    }
    /**
     * 获取联系方式
     * @param id
     * @return
     */
    @Override
    public ContactInformationRes getContactInformation(Integer id) {
        HouseResource houseResource = this.selectById(id);
        AppUser appUser = appUserService.selectById(houseResource.getAppUserId());
        ContactInformationRes contactInformationRes = new ContactInformationRes();
        contactInformationRes.setWhatsApp(appUser.getWatchApp());
        contactInformationRes.setPhone(appUser.getPhone());
        return contactInformationRes;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HouseTypeServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.HouseTypeMapper;
import com.stylefeng.guns.modular.system.model.HouseType;
import com.stylefeng.guns.modular.system.service.IHouseTypeService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 14:45
 */
@Service
public class HouseTypeServiceImpl extends ServiceImpl<HouseTypeMapper, HouseType> implements IHouseTypeService {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HousingDemandDistrictServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.HousingDemandDistrictMapper;
import com.stylefeng.guns.modular.system.model.HousingDemandDistrict;
import com.stylefeng.guns.modular.system.service.IHousingDemandDistrictService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 9:50
 */
@Service
public class HousingDemandDistrictServiceImpl extends ServiceImpl<HousingDemandDistrictMapper, HousingDemandDistrict> implements IHousingDemandDistrictService {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/HousingDemandServiceImpl.java
New file
@@ -0,0 +1,272 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.dao.HousingDemandMapper;
import com.stylefeng.guns.modular.system.model.*;
import com.stylefeng.guns.modular.system.service.*;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.util.UUIDUtil;
import com.stylefeng.guns.modular.system.warpper.req.HousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.req.SearchHousingDemandReq;
import com.stylefeng.guns.modular.system.warpper.res.ContactInformationRes;
import com.stylefeng.guns.modular.system.warpper.res.HousingDemandInfoRes;
import com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandListRes;
import com.stylefeng.guns.modular.system.warpper.res.SearchHousingDemandRes;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 16:59
 */
@Service
public class HousingDemandServiceImpl extends ServiceImpl<HousingDemandMapper, HousingDemand> implements IHousingDemandService {
    @Autowired
    private IAppUserService appUserService;
    @Autowired
    private IHousingDemandDistrictService housingDemandDistrictService;
    @Autowired
    private IRegionService regionService;
    @Autowired
    private IHouseTypeService houseTypeService;
    @Autowired
    private ICollectionHousingDemandService collectionHousingDemandService;
    /**
     * 添加房源需求
     * @param req
     */
    @Override
    public ResultUtil addHousingDemand(HousingDemandReq req) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        HousingDemand housingDemand = new HousingDemand();
        BeanUtils.copyProperties(req, housingDemand);
        try {
            housingDemand.setCode(UUIDUtil.getRandomCode(8));
        } catch (Exception e) {
            e.printStackTrace();
        }
        housingDemand.setIsDelete(0);
        housingDemand.setInsertTime(new Date());
        housingDemand.setInsertUserId(appUser.getId());
        this.insert(housingDemand);
        List<HousingDemandDistrict> list = new ArrayList<>();
        if(ToolUtil.isNotEmpty(req.getDistrict())){
            JSONArray jsonArray = JSON.parseArray(req.getDistrict());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Integer cityId = jsonObject.getInteger("cityId");
                Integer districtId = jsonObject.getInteger("districtId");
                //不限区域
                if(null == districtId){
                    districtId = 0;
                }
                HousingDemandDistrict housingDemandDistrict = new HousingDemandDistrict();
                housingDemandDistrict.setCityId(cityId);
                housingDemandDistrict.setDistrictId(districtId);
                housingDemandDistrict.setHousingDemandId(housingDemand.getId());
                list.add(housingDemandDistrict);
            }
        }
        if(list.size() > 0){
            housingDemandDistrictService.insertBatch(list);
        }
        return ResultUtil.success();
    }
    /**
     * 搜索求房源列表数据
     * @param req
     * @return
     */
    @Override
    public SearchHousingDemandRes searchHousingDemand(SearchHousingDemandReq req) {
        req.setPageNum(req.getPageNum() - 1 * req.getPageSize());
        //区域
        List<String> district = null;
        if(StringUtils.hasLength(req.getDistrict())){
            district = new ArrayList<>();
            JSONArray jsonArray = JSON.parseArray(req.getDistrict());
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                Integer cityId = jsonObject.getInteger("cityId");
                Integer districtId = jsonObject.getInteger("districtId");
                //不限区域
                if(null == districtId){
                    districtId = 0;
                }
                district.add("cityId:" + cityId + ",districtId:" + districtId);
            }
        }
        //价格范围
        Double saleAmountStart = null;
        Double saleAmountEnd = null;
        if(StringUtils.hasLength(req.getSaleAmount())){
            String[] split = req.getSaleAmount().split("-");
            saleAmountStart = Double.valueOf(split[0]);
            saleAmountEnd = Double.valueOf(split[1]);
        }
        //户型
        List<String> houseModels = null;
        if(StringUtils.hasLength(req.getHouseModel())){
            String[] split = req.getHouseModel().split(",");
            houseModels = Arrays.asList(split);
        }
        //房型
        List<Integer> houseTypeIds = null;
        if(StringUtils.hasLength(req.getHouseTypeId())){
            houseTypeIds = new ArrayList<>();
            String[] split = req.getHouseTypeId().split(",");
            for (String s : split) {
                houseTypeIds.add(Integer.valueOf(s));
            }
        }
        SearchHousingDemandRes searchHouseResource = new SearchHousingDemandRes();
        List<SearchHousingDemandListRes> searchHouseResourceListRes = this.baseMapper.searchHousingDemand(req, district, saleAmountStart, saleAmountEnd, houseModels, houseTypeIds);
        for (SearchHousingDemandListRes searchHouseResourceListRe : searchHouseResourceListRes) {
            List<HousingDemandDistrict> list = housingDemandDistrictService.selectList(new EntityWrapper<HousingDemandDistrict>()
                    .eq("housing_demand_id", searchHouseResourceListRe.getId()));
            List<String> dis = new ArrayList<>();
            for (HousingDemandDistrict housingDemandDistrict : list) {
                Region region = regionService.selectById(housingDemandDistrict.getCityId());
                Region region1 = regionService.selectById(housingDemandDistrict.getDistrictId());
                dis.add(region.getName() + ">" + (null == region1 ? "不限" : region1.getName()));
            }
            //城市不限用空判断
            searchHouseResourceListRe.setAddress(dis.size() == 0 ? null : dis);
        }
        searchHouseResource.setList(searchHouseResourceListRes);
        Integer integer = this.baseMapper.searchHousingDemandCount(req, district, saleAmountStart, saleAmountEnd, houseModels, houseTypeIds);
        searchHouseResource.setTotal(integer);
        return searchHouseResource;
    }
    /**
     * 获取求房源详情
     * @param id
     * @return
     */
    @Override
    public HousingDemandInfoRes housingDemandInfo(Integer id) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        HousingDemand housingDemand = this.selectById(id);
        HousingDemandInfoRes housingDemandInfoRes = new HousingDemandInfoRes();
        AppUser appUser = appUserService.getAppUser();
        housingDemandInfoRes.setId(id);
        housingDemandInfoRes.setTitle(housingDemand.getTitle());
        housingDemandInfoRes.setSaleAmount(housingDemand.getSaleAmount());
        housingDemandInfoRes.setHouseModel(housingDemand.getHouseModel());
        housingDemandInfoRes.setRentalDuration(housingDemand.getRentalDuration());
        housingDemandInfoRes.setSaleDate(housingDemand.getSaleDate());
        String[] split = housingDemand.getHouseTypeId().split(",");
        String houseType = "";
        for (String s : split) {
            HouseType htype = houseTypeService.selectById(s);
            houseType += htype.getName() + " / ";
        }
        housingDemandInfoRes.setHouseType(houseType.substring(0, houseType.lastIndexOf("/")));
        housingDemandInfoRes.setFloor(housingDemand.getFloor());
        housingDemandInfoRes.setElevator(housingDemand.getElevator());
        housingDemandInfoRes.setDryingArea(housingDemand.getDryingArea());
        housingDemandInfoRes.setHouseArea(housingDemand.getHouseArea());
        housingDemandInfoRes.setKeepPet(housingDemand.getKeepPet());
        List<HousingDemandDistrict> list = housingDemandDistrictService.selectList(new EntityWrapper<HousingDemandDistrict>()
                .eq("housing_demand_id", id));
        List<String> dis = new ArrayList<>();
        for (HousingDemandDistrict housingDemandDistrict : list) {
            Region region = regionService.selectById(housingDemandDistrict.getCityId());
            Region region1 = regionService.selectById(housingDemandDistrict.getDistrictId());
            dis.add(region.getName() + ">" + (null == region1 ? "不限" : region1.getName()));
        }
        //城市不限用空判断
        housingDemandInfoRes.setAddress(dis.size() == 0 ? null : dis);
        housingDemandInfoRes.setMoreIntroduction(housingDemand.getMoreIntroduction());
        housingDemandInfoRes.setViewsNumber(housingDemand.getViewsNumber());
        AppUser appUser1 = appUserService.selectById(housingDemand.getAppUserId());
        housingDemandInfoRes.setProfilePhoto(appUser1.getProfilePhoto());
        housingDemandInfoRes.setNickname(appUser1.getNickname());
        housingDemandInfoRes.setInsertTime(sdf.format(housingDemand.getInsertTime()));
        housingDemandInfoRes.setUpdateTime(sdf.format(housingDemand.getUpdateTime()));
        housingDemandInfoRes.setCode(housingDemand.getCode());
        int collectionTimes = collectionHousingDemandService.selectCount(new EntityWrapper<CollectionHousingDemand>().eq("housing_demand_id", id));
        housingDemandInfoRes.setCollectionTimes(collectionTimes);
        housingDemandInfoRes.setCollection(0);
        if(null != appUser){
            int collection = collectionHousingDemandService.selectCount(new EntityWrapper<CollectionHousingDemand>().eq("housing_demand_id", id).eq("app_user_id", appUser.getId()));
            housingDemandInfoRes.setCollection(0 == collection ? 0 : 1);
        }
        //添加访问次数记录
        addViewsNumber(housingDemand);
        return housingDemandInfoRes;
    }
    /**
     * 添加访问次数记录
     * @param housingDemand
     */
    private void addViewsNumber(HousingDemand housingDemand){
        housingDemand.setViewsNumber((null == housingDemand.getViewsNumber() ? 0 : housingDemand.getViewsNumber()) + 1);
        this.updateById(housingDemand);
    }
    /**
     * 获取联系方式
     * @param id
     * @return
     */
    @Override
    public ContactInformationRes getContactInformation(Integer id) {
        HousingDemand houseResource = this.selectById(id);
        AppUser appUser = appUserService.selectById(houseResource.getAppUserId());
        ContactInformationRes contactInformationRes = new ContactInformationRes();
        contactInformationRes.setWhatsApp(appUser.getWatchApp());
        contactInformationRes.setPhone(appUser.getPhone());
        return contactInformationRes;
    }
    /**
     * 获取剩余发布数量
     * @return
     */
    @Override
    public ResultUtil<Integer> getSurplusPushNumber() {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        int num = this.selectCount(new EntityWrapper<HousingDemand>().eq("is_delete", 0)
                .eq("app_user_id", appUser.getId())
                .eq("status", 1)
        );
        return ResultUtil.success(appUser.getUserType() != 3 ? (3 - num) : -1);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/LoginLogServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.LoginLogMapper;
import com.stylefeng.guns.modular.system.model.LoginLog;
import com.stylefeng.guns.modular.system.service.ILoginLogService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 登录记录 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
@Service
public class LoginLogServiceImpl extends ServiceImpl<LoginLogMapper, LoginLog> implements ILoginLogService {
    @Override
    public List<Map<String, Object>> getLoginLogs(Page<LoginLog> page, String beginTime, String endTime, String logName, String orderByField, boolean asc) {
        return this.baseMapper.getLoginLogs(page, beginTime, endTime, logName, orderByField, asc);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/MenuServiceImpl.java
New file
@@ -0,0 +1,90 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.node.MenuNode;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.modular.system.dao.MenuMapper;
import com.stylefeng.guns.modular.system.model.Menu;
import com.stylefeng.guns.modular.system.service.IMenuService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
 * 菜单服务
 *
 * @author fengshuonan
 * @date 2017-05-05 22:20
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
    @Resource
    private MenuMapper menuMapper;
    @Override
    public void delMenu(Long menuId) {
        //删除菜单
        this.menuMapper.deleteById(menuId);
        //删除关联的relation
        this.menuMapper.deleteRelationByMenu(menuId);
    }
    @Override
    public void delMenuContainSubMenus(Long menuId) {
        Menu menu = menuMapper.selectById(menuId);
        //删除当前菜单
        delMenu(menuId);
        //删除所有子菜单
        Wrapper<Menu> wrapper = new EntityWrapper<>();
        wrapper = wrapper.like("pcodes", "%[" + menu.getCode() + "]%");
        List<Menu> menus = menuMapper.selectList(wrapper);
        for (Menu temp : menus) {
            delMenu(temp.getId());
        }
    }
    @Override
    public List<Map<String, Object>> selectMenus(String condition, String level) {
        return this.baseMapper.selectMenus(condition, level);
    }
    @Override
    public List<Long> getMenuIdsByRoleId(Integer roleId) {
        return this.baseMapper.getMenuIdsByRoleId(roleId);
    }
    @Override
    public List<ZTreeNode> menuTreeList() {
        return this.baseMapper.menuTreeList();
    }
    @Override
    public List<ZTreeNode> menuTreeListByMenuIds(List<Long> menuIds) {
        return this.baseMapper.menuTreeListByMenuIds(menuIds);
    }
    @Override
    public int deleteRelationByMenu(Long menuId) {
        return this.baseMapper.deleteRelationByMenu(menuId);
    }
    @Override
    public List<String> getResUrlsByRoleId(Integer roleId) {
        return this.baseMapper.getResUrlsByRoleId(roleId);
    }
    @Override
    public List<MenuNode> getMenusByRoleIds(List<Integer> roleIds) {
        return this.baseMapper.getMenusByRoleIds(roleIds);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/NoticeServiceImpl.java
New file
@@ -0,0 +1,27 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.NoticeMapper;
import com.stylefeng.guns.modular.system.model.Notice;
import com.stylefeng.guns.modular.system.service.INoticeService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 通知表 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
@Service
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements INoticeService {
    @Override
    public List<Map<String, Object>> list(String condition) {
        return this.baseMapper.list(condition);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/OperationLogServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.OperationLogMapper;
import com.stylefeng.guns.modular.system.model.OperationLog;
import com.stylefeng.guns.modular.system.service.IOperationLogService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 操作日志 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
@Service
public class OperationLogServiceImpl extends ServiceImpl<OperationLogMapper, OperationLog> implements IOperationLogService {
    @Override
    public List<Map<String, Object>> getOperationLogs(Page<OperationLog> page, String beginTime, String endTime, String logName, String s, String orderByField, boolean asc) {
        return this.baseMapper.getOperationLogs(page, beginTime, endTime, logName, s, orderByField, asc);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RegionServiceImpl.java
New file
@@ -0,0 +1,19 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.RegionMapper;
import com.stylefeng.guns.modular.system.model.Region;
import com.stylefeng.guns.modular.system.service.IRegionService;
import com.stylefeng.guns.modular.system.warpper.res.DistrictRes;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class RegionServiceImpl extends ServiceImpl<RegionMapper, Region> implements IRegionService {
    @Override
    public List<DistrictRes> getDistrict(Integer parentId) {
        return this.baseMapper.getDistrict(parentId);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RelationServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.RelationMapper;
import com.stylefeng.guns.modular.system.model.Relation;
import com.stylefeng.guns.modular.system.service.IRelationService;
import org.springframework.stereotype.Service;
/**
 * <p>
 * 角色和菜单关联表 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
@Service
public class RelationServiceImpl extends ServiceImpl<RelationMapper, Relation> implements IRelationService {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReportHouseResourceServiceImpl.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.ReportHouseResourceMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.model.ReportHouseResource;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.service.IReportHouseResourceService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.ReportHouseResourceReq;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/20 15:30
 */
@Service
public class ReportHouseResourceServiceImpl extends ServiceImpl<ReportHouseResourceMapper, ReportHouseResource> implements IReportHouseResourceService {
    @Autowired
    private IAppUserService appUserService;
    /**
     * 添加举报内容
     * @param req
     */
    @Override
    public ResultUtil addReportHouseResource(ReportHouseResourceReq req) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        //组装数据对象
        ReportHouseResource reportHouseResource = new ReportHouseResource();
        reportHouseResource.setAppUserId(appUser.getId());
        reportHouseResource.setContent(req.getContent());
        reportHouseResource.setHouseResourceId(req.getHouseResourceId());
        reportHouseResource.setInsertTime(new Date());
        this.insert(reportHouseResource);
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/ReportHousingDemandServiceImpl.java
New file
@@ -0,0 +1,45 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.ReportHousingDemandMapper;
import com.stylefeng.guns.modular.system.model.AppUser;
import com.stylefeng.guns.modular.system.model.ReportHousingDemand;
import com.stylefeng.guns.modular.system.service.IAppUserService;
import com.stylefeng.guns.modular.system.service.IReportHousingDemandService;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.warpper.req.ReportHousingDemandReq;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 11:55
 */
@Service
public class ReportHousingDemandServiceImpl extends ServiceImpl<ReportHousingDemandMapper, ReportHousingDemand> implements IReportHousingDemandService {
    @Autowired
    private IAppUserService appUserService;
    /**
     * 添加举报求房源数据
     * @param req
     */
    @Override
    public ResultUtil addReportHousingDemand(ReportHousingDemandReq req) {
        AppUser appUser = appUserService.getAppUser();
        if(null == appUser){
            return ResultUtil.tokenErr();
        }
        ReportHousingDemand reportHousingDemand = new ReportHousingDemand();
        BeanUtils.copyProperties(req, reportHousingDemand);
        reportHousingDemand.setAppUserId(appUser.getId());
        reportHousingDemand.setInsertTime(new Date());
        this.insert(reportHousingDemand);
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/RoleServiceImpl.java
New file
@@ -0,0 +1,73 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.node.ZTreeNode;
import com.stylefeng.guns.core.util.Convert;
import com.stylefeng.guns.modular.system.dao.RelationMapper;
import com.stylefeng.guns.modular.system.dao.RoleMapper;
import com.stylefeng.guns.modular.system.model.Relation;
import com.stylefeng.guns.modular.system.model.Role;
import com.stylefeng.guns.modular.system.service.IRoleService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RelationMapper relationMapper;
    @Override
    @Transactional(readOnly = false)
    public void setAuthority(Integer roleId, String ids) {
        // 删除该角色所有的权限
        this.roleMapper.deleteRolesById(roleId);
        // 添加新的权限
        for (Long id : Convert.toLongArray(true, Convert.toStrArray(",", ids))) {
            Relation relation = new Relation();
            relation.setRoleid(roleId);
            relation.setMenuid(id);
            this.relationMapper.insert(relation);
        }
    }
    @Override
    @Transactional(readOnly = false)
    public void delRoleById(Integer roleId) {
        //删除角色
        this.roleMapper.deleteById(roleId);
        // 删除该角色所有的权限
        this.roleMapper.deleteRolesById(roleId);
    }
    @Override
    public List<Map<String, Object>> selectRoles(String condition) {
        return this.baseMapper.selectRoles(condition);
    }
    @Override
    public int deleteRolesById(Integer roleId) {
        return this.baseMapper.deleteRolesById(roleId);
    }
    @Override
    public List<ZTreeNode> roleTreeList() {
        return this.baseMapper.roleTreeList();
    }
    @Override
    public List<ZTreeNode> roleTreeListByRoleId(String[] roleId) {
        return this.baseMapper.roleTreeListByRoleId(roleId);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SearchHistoryConditionServiceImpl.java
New file
@@ -0,0 +1,15 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.SearchHistoryConditionMapper;
import com.stylefeng.guns.modular.system.model.SearchHistoryCondition;
import com.stylefeng.guns.modular.system.service.ISearchHistoryConditionService;
import org.springframework.stereotype.Service;
/**
 * @author zhibing.pu
 * @Date 2023/11/14 11:01
 */
@Service
public class SearchHistoryConditionServiceImpl extends ServiceImpl<SearchHistoryConditionMapper, SearchHistoryCondition> implements ISearchHistoryConditionService {
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/SysDataTypeServiceImpl.java
New file
@@ -0,0 +1,29 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.modular.system.dao.SysDataTypeMapper;
import com.stylefeng.guns.modular.system.model.SysDataType;
import com.stylefeng.guns.modular.system.service.ISysDataTypeService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * @author zhibing.pu
 * @Date 2023/11/23 15:35
 */
@Service
public class SysDataTypeServiceImpl extends ServiceImpl<SysDataTypeMapper, SysDataType> implements ISysDataTypeService {
    /**
     * 获取类别数据
     * @param type
     * @return
     */
    @Override
    public List<SysDataType> getSysDataType(Integer type) {
        return this.selectList(new EntityWrapper<SysDataType>().eq("type", type));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/service/impl/UserServiceImpl.java
New file
@@ -0,0 +1,54 @@
package com.stylefeng.guns.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.stylefeng.guns.core.datascope.DataScope;
import com.stylefeng.guns.modular.system.dao.UserMapper;
import com.stylefeng.guns.modular.system.model.User;
import com.stylefeng.guns.modular.system.service.IUserService;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/**
 * <p>
 * 管理员表 服务实现类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @Override
    public int setStatus(Integer userId, int status) {
        return this.baseMapper.setStatus(userId, status);
    }
    @Override
    public int changePwd(Integer userId, String pwd) {
        return this.baseMapper.changePwd(userId, pwd);
    }
    @Override
    public List<Map<String, Object>> selectUsers(DataScope dataScope, String name, String beginTime, String endTime, Integer deptid) {
        return this.baseMapper.selectUsers(dataScope, name, beginTime, endTime, deptid);
    }
    @Override
    public int setRoles(Integer userId, String roleIds) {
        return this.baseMapper.setRoles(userId, roleIds);
    }
    @Override
    public User getByAccount(String account) {
        return this.baseMapper.getByAccount(account);
    }
    @Override
    public Map<String,Object> getSysUserDetails(Integer id) {
        return this.baseMapper.getSysUserDetails(id);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ManagerUser.java
New file
@@ -0,0 +1,97 @@
package com.stylefeng.guns.modular.system.transfer;
import java.util.Date;
/**
 * 管理员的信息封装
 *
 * @author fengshuonan
 * @Date 2017年1月11日 下午7:46:53
 */
public class ManagerUser {
    private String userId;
    /* 用户账号 */
    private String userNo;
    /* 用户姓名 */
    private String userName;
    private String userPhone;
    //1:超级管理员  2:管理员
    private String userRole;
    /* 1:登录状态 2:退出状态 3:停用状态 */
    private Integer userStatus;
    private Date createTime;
    private Date loginTime;
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserNo() {
        return userNo;
    }
    public void setUserNo(String userNo) {
        this.userNo = userNo;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPhone() {
        return userPhone;
    }
    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }
    public String getUserRole() {
        return userRole;
    }
    public void setUserRole(String userRole) {
        this.userRole = userRole;
    }
    public Integer getUserStatus() {
        return userStatus;
    }
    public void setUserStatus(Integer userStatus) {
        this.userStatus = userStatus;
    }
    public Date getCreateTime() {
        return createTime;
    }
    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
    public Date getLoginTime() {
        return loginTime;
    }
    public void setLoginTime(Date loginTime) {
        this.loginTime = loginTime;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ReqAddManager.java
New file
@@ -0,0 +1,76 @@
package com.stylefeng.guns.modular.system.transfer;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
/**
 * 添加管理员的请求bean
 *
 * @author fengshuonan
 * @Date 2017年1月12日 下午6:46:24
 */
public class ReqAddManager {
    // 用户姓名
    @NotNull
    private String userName;
    // 用户账号
    @NotNull
    private String userNo;
    // 手机号
    @NotNull
    @Length(min = 11, max = 11)
    private String userPhone;
    // 1:超级管理员 2:管理员
    @NotNull
    private String userRole;
    // 密码
    @NotNull
    private String userPassword;
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserNo() {
        return userNo;
    }
    public void setUserNo(String userNo) {
        this.userNo = userNo;
    }
    public String getUserPhone() {
        return userPhone;
    }
    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }
    public String getUserRole() {
        return userRole;
    }
    public void setUserRole(String userRole) {
        this.userRole = userRole;
    }
    public String getUserPassword() {
        return userPassword;
    }
    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/ReqEditManager.java
New file
@@ -0,0 +1,60 @@
package com.stylefeng.guns.modular.system.transfer;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotNull;
/**
 * 编辑管理员的请求
 *
 * @author fengshuonan
 * @Date 2017年1月15日 下午10:29:16
 */
public class ReqEditManager {
    @NotNull
    private String userId;
    /* 用户姓名 */
    @NotNull
    private String userName;
    private String userPassword;
    @NotNull
    @Length(min = 11, max = 11)
    private String userPhone;
    public String getUserId() {
        return userId;
    }
    public void setUserId(String userId) {
        this.userId = userId;
    }
    public String getUserName() {
        return userName;
    }
    public void setUserName(String userName) {
        this.userName = userName;
    }
    public String getUserPassword() {
        return userPassword;
    }
    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }
    public String getUserPhone() {
        return userPhone;
    }
    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/transfer/UserDto.java
New file
@@ -0,0 +1,153 @@
package com.stylefeng.guns.modular.system.transfer;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
 * 用户传输bean
 *
 * @author stylefeng
 * @Date 2017/5/5 22:40
 */
public class UserDto{
    private Integer id;
    private String account;
    private String password;
    private String salt;
    private String name;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private Integer sex;
    private String email;
    private String phone;
    private String roleid;
    private Integer deptid;
    private Integer status;
    private Date createtime;
    private Integer version;
    private String avatar;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getAccount() {
        return account;
    }
    public void setAccount(String account) {
        this.account = account;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSalt() {
        return salt;
    }
    public void setSalt(String salt) {
        this.salt = salt;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public String getRoleid() {
        return roleid;
    }
    public void setRoleid(String roleid) {
        this.roleid = roleid;
    }
    public Integer getDeptid() {
        return deptid;
    }
    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }
    public Integer getStatus() {
        return status;
    }
    public void setStatus(Integer status) {
        this.status = status;
    }
    public Date getCreatetime() {
        return createtime;
    }
    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
    public Integer getVersion() {
        return version;
    }
    public void setVersion(Integer version) {
        this.version = version;
    }
    public String getAvatar() {
        return avatar;
    }
    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/AESUtil.java
New file
@@ -0,0 +1,87 @@
package com.stylefeng.guns.modular.system.util;
import com.stylefeng.guns.core.util.ToolUtil;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
 * 定义AES加密解密工具类
 */
public class AESUtil {
    private static final String KEY_ALGORITHM = "AES";//加密方式
    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";//默认的加密算法
    private static final String KEY = "f8awbemr85fv1nz6";//密码
    private static final String IV_PARAMETER = "ghoyth86kgm0vuww";//偏移量
    private static final String CHARSET = "UTF-8";//编码
    /**
     * 加密操作
     * @param content  待加密内容
     * @return
     * @throws Exception
     */
    public static String encrypt(String content) {
        try {
            if(ToolUtil.isEmpty(content)){
                return content;
            }
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            byte[] raw = KEY.getBytes(CHARSET);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
            byte[] encrypted = cipher.doFinal(content.getBytes(CHARSET));
            return Base64Utils.encodeToString(encrypted);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     *解密操作
     * @param content 待解密内容
     * @return
     * @throws Exception
     */
    public static String decrypt(String content) {
        try {
            if(ToolUtil.isEmpty(content)){
                return content;
            }
            byte[] raw = KEY.getBytes(CHARSET);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);
            IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = Base64Utils.decodeFromString(content);
            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original, CHARSET);
            return originalString;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
    public static void main(String[] ages){
//        String encrypt = AESUtil.encrypt("13636090142");
//        System.err.println(encrypt);
        String travel = AESUtil.decrypt("bP8czy4m041BonJb0WFsRg==");
        System.err.println(travel);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/DataUtil.java
New file
@@ -0,0 +1,120 @@
package com.stylefeng.guns.modular.system.util;
import com.stylefeng.guns.core.util.DateUtil;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
//日期转换年龄
public class DataUtil {
    private static TimeZone tz = TimeZone.getTimeZone("GMT+8");
    public static int getAge(Date dateOfBirth) {
        int age = 0;
        Calendar born = Calendar.getInstance();
        Calendar now = Calendar.getInstance();
        if (dateOfBirth != null) {
            now.setTime(new Date());
            born.setTime(dateOfBirth);
            if (born.after(now)) {
                return age;
//                throw new IllegalArgumentException("年龄不能超过当前日期");
            }
            age = now.get(Calendar.YEAR) - born.get(Calendar.YEAR);
            int nowDayOfYear = now.get(Calendar.DAY_OF_YEAR);
            int bornDayOfYear = born.get(Calendar.DAY_OF_YEAR);
//            logger.debug("nowDayOfYear:" + nowDayOfYear + " bornDayOfYear:" + bornDayOfYear);
            if (nowDayOfYear < bornDayOfYear) {
                age -= 1;
            }
        }
        return age;
    }
    /**
     * 字符串日期转Date yyyy-MM-dd HH:mm:ss
     *
     * @param
     * @return
     */
    public static Date getDate_str3(String dateStr) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(tz);
        if ("".equals(dateStr)) {
            dateStr = sdf.format(DateUtil.getDate());
        }
        Date date = null;
        try {
            date = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
    /**
     * 日期转毫秒
     *
     * @param date
     * @return
     */
    public static long getMillisecond(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String newDate = "";
        if (!"".equals(date)) {
            newDate = sdf.format(date);
        } else {
            newDate = sdf.format(DateUtil.getDate());
        }
        long millisecond = 0;
        try {
            millisecond = sdf.parse(newDate).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return millisecond;
    }
    /**
     * 两日期相差天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long getMinusDay(Date startDate, Date endDate) {
        long startMillisecond = getMillisecond(startDate);
        long endMillisecond = getMillisecond(endDate);
        long minusMillisecond = endMillisecond - startMillisecond;
        long day = 0;
        if (minusMillisecond < 0) {
            day = 0;
        } else {
            day = minusMillisecond / (24 * 3600 * 1000);
        }
        return day;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/EmptyUtil.java
New file
@@ -0,0 +1,55 @@
package com.stylefeng.guns.modular.system.util;
import java.util.List;
public class EmptyUtil {
    /**
     * 判断对象为空
     *
     * @param obj
     *      对象名
     * @return 是否为空
     */
    @SuppressWarnings("rawtypes")
    public static boolean isEmpty(Object obj)
    {
        if (obj == null)
        {
            return true;
        }
        if ((obj instanceof List))
        {
            return ((List) obj).size() == 0;
        }
        if ((obj instanceof String))
        {
            return ((String) obj).trim().equals("");
        }
        return false;
    }
    /**
     * 判断对象不为空
     *
     * @param obj
     *      对象名
     * @return 是否不为空
     */
    public static boolean isNotEmpty(Object obj)
    {
        return !isEmpty(obj);
    }
    /**
     * 富文本格式转换
     * @param value
     * @return
     */
    public static String cleanXSS(String value) {
        //You'll need to remove the spaces from the html entities below
        value = value.replaceAll("& lt;", "<").replaceAll("& gt;", ">");
        value = value.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;");
        return value;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/ExcelUtil.java
New file
@@ -0,0 +1,207 @@
package com.stylefeng.guns.modular.system.util;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
 * 定义Excel工具类
 */
@Component
public class ExcelUtil {
    public List<List<List<String>>> upload(MultipartFile file){
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //获取文件名
        String fileName=file.getOriginalFilename();
        List<List<List<String>>> list = null;
        if(validateExcel(fileName)) {
            // 根据版本选择创建Workbook的方式
            Workbook wb = null;
            // 根据文件名判断文件是2003版本还是2007版本
            if (isExcel2007(fileName)) {
                try {
                    wb = new XSSFWorkbook(inputStream);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else {
                try {
                    wb = new HSSFWorkbook(inputStream);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            int num = wb.getNumberOfSheets();//获取页数
            list = new ArrayList<>();
            for (int i = 0; i < num; i++) {
                List<List<String>> sheetList = new ArrayList<>();
                //获取每一页对象
                Sheet sheet = wb.getSheetAt(i);
                // 得到Excel的行数
                int totalRows = sheet.getPhysicalNumberOfRows();
                for (int j = 0; j < totalRows; j++) {
                    if (j == 0) {
                        continue;// 标题行
                    }
                    Row row = sheet.getRow(j);// 获取索引为i的行数据
                    if(null == row){
                        continue;
                    }
                    int index = sheet.getRow(0).getPhysicalNumberOfCells();//获取标题的列数用于遍历
                    List<String> strings = new ArrayList<>();
                    int in = 0;//用于遍历单元格判断该行是否全为空值
                    for (int k = 0; k < index; k++) {//遍历获取每个单元格的数据
                        String str = null;
                        Cell cell = row.getCell(k);
                        if(cell == null) {
                            str = "";
                            in++;
                        }else {
                            switch (cell.getCellType()) {//判断数据类型取值
                                case NUMERIC :
                                    if (DateUtil.isCellDateFormatted(cell)) {
                                        Date theDate = cell.getDateCellValue();
                                        str = String.valueOf(theDate.getTime());
                                    }else{
                                        String string = String.valueOf(cell.getNumericCellValue());
                                        str = string.substring(0, string.indexOf("."));
                                    }
                                    break;
                                case STRING :
                                    str = cell.getStringCellValue();
                                    if(str == null) {
                                        str = "";
                                        in++;
                                    }
                                    break;
                                case _NONE :
                                    System.err.println("_NONE");
                                    break;
                                case FORMULA :
                                    System.err.println("FORMULA");
                                    break;
                                case BLANK :
                                    str = cell.getStringCellValue();
                                    if(str.equals("")) {
                                        str = "";
                                        in++;
                                    }
                                    break;
                                case BOOLEAN :
                                    System.err.println("BOOLEAN");
                                    break;
                                case ERROR :
                                    System.err.println("ERROR");
                                    break;
                                default:
                                    break;
                            }
                        }
                        strings.add(String.valueOf(str).trim());
                    }
                    if(in != index) {//判断如果每个单元格都为null则不需要添加到集合中
                        sheetList.add(strings);
                    }
                }
                list.add(sheetList);
            }
        }
        return list;
    }
    // @描述:是否是2003的excel,返回true是2003
    public static boolean isExcel2003(String filePath)  {
        return filePath.matches("^.+\\.(?i)(xls)$");
    }
    //@描述:是否是2007的excel,返回true是2007
    public static boolean isExcel2007(String filePath)  {
        return filePath.matches("^.+\\.(?i)(xlsx)$");
    }
    /**
     * 验证EXCEL文件
     * @param filePath
     * @return
     */
    public static boolean validateExcel(String filePath){
        if (filePath == null || !(isExcel2003(filePath) || isExcel2007(filePath))){
            return false;
        }
        return true;
    }
    /**
     * 将数据写入Excel中
     * @param titles    标题
     * @param datas     数据
     * @return
     */
    public HSSFWorkbook writeDataToExcel(List<List<String>> titles, List<List<List<String>>> datas) {
        HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
        for(int i = 0; i < titles.size(); i++){
            HSSFSheet hssfSheet = hssfWorkbook.createSheet();
            hssfSheet.setColumnWidth(0, 6 * 256);
            hssfSheet.setDefaultRowHeightInPoints(20f);
            HSSFRow hssfRow = hssfSheet.createRow(0);//设置第一行数据(标题)
            HSSFCellStyle style = hssfWorkbook.createCellStyle();
            HSSFFont font = hssfWorkbook.createFont();
            font.setBold(true);
            style.setFont(font);
            style.setAlignment(HorizontalAlignment.CENTER);
            for (int l = 0; l < titles.get(i).size(); l++) {
                HSSFCell hssfCell = hssfRow.createCell(l);
                hssfCell.setCellType(CellType.STRING);//设置表格类型
                hssfCell.setCellValue(titles.get(i).get(l));
                hssfCell.setCellStyle(style);
                if(l > 0) {
                    hssfSheet.setColumnWidth(l , 20 * 256);
                }
            }
            //将数据添加到表格中
            List<String> data = null;
            for (int l = 0; l < datas.get(i).size(); l++) {
                hssfRow = hssfSheet.createRow(l + 1);
                data = datas.get(i).get(l);
                for (int j = 0; j < data.size(); j++) {
                    HSSFCell hssfCell = hssfRow.createCell(j);
                    hssfCell.setCellType(CellType.STRING);//设置表格类型
                    hssfCell.setCellValue(data.get(j));
                }
            }
        }
        return hssfWorkbook;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GDMapGeocodingUtil.java
New file
@@ -0,0 +1,157 @@
package com.stylefeng.guns.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 高德地图的地理编码工具类
 */
@Component
public class GDMapGeocodingUtil {
    private String key = "cc34d80527f0e06b8ee0aac3dab0126a";
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 将行政区域名称转化为坐标
     * @param province
     * @param city
     * @param county
     * @param address
     * @return
     */
    public Map<String, Object> geocoding(String province, String city, String county, String address) throws Exception{
        Map<String, Object> map = new HashMap<>();
        if(ToolUtil.isEmpty(province)){
            map.put("status", -1);
            map.put("data", "省不能为空");
            return map;
        }
        if((ToolUtil.isEmpty(city) && ToolUtil.isNotEmpty(county)) || (ToolUtil.isEmpty(city) && ToolUtil.isNotEmpty(address))){
            map.put("status", -1);
            map.put("data", "市不能为空");
            return map;
        }
        if((ToolUtil.isEmpty(county) && ToolUtil.isNotEmpty(address))){
            map.put("status", -1);
            map.put("data", "县/区不能为空");
            return map;
        }
        String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON";
        url += "&address=" + province + (ToolUtil.isNotEmpty(city) ? city : "") + (ToolUtil.isNotEmpty(county) ? county : "") + (ToolUtil.isNotEmpty(address) ? address : "");
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        String status = jsonObject.getString("status");
        List<String> list = new ArrayList<>();
//        gdInterfaceService.saveData("https://restapi.amap.com/v3/geocode/geo", "行政区域转经纬度");
        if(status.equals("1")){
            JSONArray geocodes = jsonObject.getJSONArray("geocodes");
            for(int i = 0; i < geocodes.size(); i++){
                String location = geocodes.getJSONObject(i).getString("location");
                list.add(location);
            }
        }
        map.put("status", 0);
        map.put("data", list);
        return map;
    }
    public Map<String, Object> geocoding(String address) throws Exception{
        Map<String, Object> map = new HashMap<>();
        String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON&address=" + address;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        String status = jsonObject.getString("status");
        List<String> list = new ArrayList<>();
//        gdInterfaceService.saveData("https://restapi.amap.com/v3/geocode/geo", "行政区域转经纬度");
        if(status.equals("1")){
            JSONArray geocodes = jsonObject.getJSONArray("geocodes");
            for(int i = 0; i < geocodes.size(); i++){
                String location = geocodes.getJSONObject(i).getString("location");
                list.add(location);
            }
        }
        map.put("status", 0);
        map.put("data", list);
        return map;
    }
    /**
     * 根据经纬度获取行政区域信息
     * @param lon
     * @param lan
     * @return
     * @throws Exception
     */
    public Map<String, String> geocode(String lon, String lan) throws Exception{
        String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        Map<String, String> map = new HashMap<>();
        if(jsonObject.getString("status").equals("1")){
            JSONObject regeocode = jsonObject.getJSONObject("regeocode");
            JSONObject addressComponent = regeocode.getJSONObject("addressComponent");
            String address = regeocode.getString("formatted_address");
            map.put("address", address);
            String code = addressComponent.getString("adcode");
            String province = addressComponent.getString("province");
            String city = addressComponent.getString("city");
            String district = addressComponent.getString("district");
            map.put("province", province);
            map.put("provinceCode", code.substring(0, 2) + "0000");
            map.put("city", city);
            map.put("cityCode", code.substring(0, 4) + "00");
            map.put("district", district);
            map.put("districtCode", code);
        }
        return map;
    }
    /**
     * 坐标转换
     * @param locations 经度和纬度用","分割,经度在前,纬度在后,经纬度小数点后不得超过6位。多个坐标对之间用”|”进行分隔最多支持40对坐标。
     * @param coordsys  可选值:gps;mapbar;baidu;autonavi(不进行转换)
     * @return
     * @throws Exception
     */
    public Map<String, String> convert(String locations, String coordsys) throws Exception{
        String url = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations=" + locations + "&coordsys=" + coordsys + "&output=json&key=" + key;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        Map<String, String> map = new HashMap<>();
        if("1".equals(jsonObject.getString("status"))){
            map.put("code", jsonObject.getString("infocode"));//"10000"
            map.put("info", jsonObject.getString("info"));//status为0时,info返回错误原;否则返回“OK”。
            map.put("locations", jsonObject.getString("locations").split(";")[0]);//转换之后的坐标。若有多个坐标,则用 “;”进行区分和间隔
        }else{
            map.put("code", jsonObject.getString("infocode"));
            map.put("info", jsonObject.getString("info"));//status为0时,info返回错误原;否则返回“OK”。
        }
        return map;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/GeodesyUtil.java
New file
@@ -0,0 +1,75 @@
package com.stylefeng.guns.modular.system.util;
import com.stylefeng.guns.core.util.ToolUtil;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 计算两个金纬度坐标之间的直线距离
 */
@Component
public class GeodesyUtil {
    /**
     * 获取直线距离
     * @param fromLonLat
     * @param toLonLat
     * @return
     */
    public Map<String, Double> getDistance(String fromLonLat, String toLonLat){
        Map<String, Double> map = null;
        if(ToolUtil.isNotEmpty(fromLonLat) && ToolUtil.isNotEmpty(toLonLat)){
            map = new HashMap<>();
            String[] from = fromLonLat.split(",");
            String[] to = toLonLat.split(",");
            GlobalCoordinates source = new GlobalCoordinates(Double.valueOf(from[1]), Double.valueOf(from[0]));
            GlobalCoordinates target = new GlobalCoordinates(Double.valueOf(to[1]), Double.valueOf(to[0]));
            double Sphere = getDistanceMeter(source, target, Ellipsoid.Sphere);
            double WGS84 = getDistanceMeter(source, target, Ellipsoid.WGS84);
            double GRS80 = getDistanceMeter(source, target, Ellipsoid.GRS80);
            double GRS67 = getDistanceMeter(source, target, Ellipsoid.GRS67);
            double ANS = getDistanceMeter(source, target, Ellipsoid.ANS);
            double WGS72 = getDistanceMeter(source, target, Ellipsoid.WGS72);
            double Clarke1858 = getDistanceMeter(source, target, Ellipsoid.Clarke1858);
            double Clarke1880 = getDistanceMeter(source, target, Ellipsoid.Clarke1880);
//            logger.debug("Sphere坐标系计算结果:"+Sphere + "米");
//            logger.debug("WGS84坐标系计算结果:"+WGS84 + "米");
//            logger.debug("GRS80坐标系计算结果:"+GRS80 + "米");
//            logger.debug("GRS67坐标系计算结果:"+GRS67 + "米");
//            logger.debug("ANS坐标系计算结果:"+ANS + "米");
//            logger.debug("WGS72坐标系计算结果:"+WGS72 + "米");
//            logger.debug("Clarke1858坐标系计算结果:"+Clarke1858 + "米");
//            logger.debug("Clarke1880坐标系计算结果:"+Clarke1880 + "米");
            map.put("Sphere", Sphere);
            map.put("WGS84", WGS84);
            map.put("GRS80", GRS80);
            map.put("GRS67", GRS67);
            map.put("ANS", ANS);
            map.put("WGS72", WGS72);
            map.put("Clarke1858", Clarke1858);
            map.put("Clarke1880", Clarke1880);
        }
        return map;
    }
    private double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid){
        //创建GeodeticCalculator,调用计算方法,传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
        return geoCurve.getEllipsoidalDistance();
    }
    public static void main(String[] ages){
        GeodesyUtil geodesyUtil = new GeodesyUtil();
        geodesyUtil.getDistance("115.481028,39.989643", "114.465302,40.004717");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/HttpRequestUtil.java
New file
@@ -0,0 +1,184 @@
package com.stylefeng.guns.modular.system.util;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.SimpleHttpConnectionManager;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
public class HttpRequestUtil {
    public static String postRequest(String url, Map<String, String> params) {
        // 构造HttpClient的实例
        HttpClient httpClient = new HttpClient();
        // 创建POST方法的实例
        PostMethod postMethod = new PostMethod(url);
        // 设置请求头信息
        postMethod.setRequestHeader("Connection", "close");
        postMethod.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        // 添加参数
        for (Map.Entry<String, String> entry : params.entrySet()) {
            postMethod.addParameter(entry.getKey(), entry.getValue());
        }
        // 使用系统提供的默认的恢复策略,设置请求重试处理,用的是默认的重试处理:请求三次
        httpClient.getParams().setBooleanParameter("http.protocol.expect-continue", false);
        // 接收处理结果
        String result = null;
        try {
            // 执行Http Post请求
            httpClient.executeMethod(postMethod);
            // 返回处理结果
            result = postMethod.getResponseBodyAsString();
        } catch (HttpException e) {
            // 发生致命的异常,可能是协议不对或者返回的内容有问题
            System.out.println("请检查输入的URL!");
            e.printStackTrace();
        } catch (IOException e) {
            // 发生网络异常
            System.out.println("发生网络异常!");
            e.printStackTrace();
        } finally {
            // 释放链接
            postMethod.releaseConnection();
            // 关闭HttpClient实例
            if (httpClient != null) {
                ((SimpleHttpConnectionManager) httpClient.getHttpConnectionManager()).shutdown();
                httpClient = null;
            }
        }
        return result;
    }
    public static String getRequest(String url, Map<String, String> params) {
        // 构造HttpClient实例
        HttpClient client = new HttpClient();
        // 拼接参数
        String paramStr = "";
        if(params!=null){
            for (String key : params.keySet()) {
                paramStr = paramStr + "&" + key + "=" + params.get(key);
            }
            paramStr = paramStr.substring(1);
        }
        // 创建GET方法的实例
        GetMethod method = new GetMethod(url + "?" + paramStr);
        // 接收返回结果
        String result = null;
        try {
            // 执行HTTP GET方法请求
            client.executeMethod(method);
            // 返回处理结果
            result = method.getResponseBodyAsString();
        } catch (HttpException e) {
            // 发生致命的异常,可能是协议不对或者返回的内容有问题
            System.out.println("请检查输入的URL!");
            e.printStackTrace();
        } catch (IOException e) {
            // 发生网络异常
            System.out.println("发生网络异常!");
            e.printStackTrace();
        } finally {
            // 释放链接
            method.releaseConnection();
            // 关闭HttpClient实例
            if (client != null) {
                ((SimpleHttpConnectionManager) client
                        .getHttpConnectionManager()).shutdown();
                client = null;
            }
        }
        return result;
    }
    /**
     * 发送网络请求
     * @param url
     * @return
     */
    public static String sendNetRequest(String url, Map<String, String> params) {
        // 构造HttpClient实例
        HttpClient client = new HttpClient();
        String paramStr = "";
        for (String key : params.keySet()) {
            paramStr = paramStr + "&" + key + "=" + params.get(key);
        }
        paramStr = paramStr.substring(1);
        System.err.println(url + "?" + paramStr);
        // 创建GET方法的实例
        GetMethod method = new GetMethod(url + "?" + paramStr);
        // 接收返回结果
        String result = null;
        try {
            // 执行HTTP GET方法请求
            client.executeMethod(method);
            // 返回处理结果
            result = method.getResponseBodyAsString();
        } catch (HttpException e) {
            // 发生致命的异常,可能是协议不对或者返回的内容有问题
            System.out.println("请检查输入的URL!");
            e.printStackTrace();
        } catch (IOException e) {
            // 发生网络异常
            System.out.println("发生网络异常!");
            e.printStackTrace();
        } finally {
            // 释放链接
            method.releaseConnection();
            // 关闭HttpClient实例
            if (client != null) {
                ((SimpleHttpConnectionManager) client.getHttpConnectionManager()).shutdown();
                client = null;
            }
        }
        return result;
    }
    /**
     * jsonp跨域请求数据响应<br/>
     * 方法名:responsejsonpData<br/>
     * @author:Mryang<br/>
     * @createTime:2016年7月31日-下午11:17:31 <br/>
     * @tel: 15198268054<br/>
     * @param request
     * @param response
     * @param map void<br/>
     * @exception <br/>
     * @since  1.0.0
     */
    public void responsejsonpData(HttpServletRequest request, HttpServletResponse response, Map<String, Object> map) {
         response.setCharacterEncoding("UTF-8");
         response.setHeader("Content-Type", "text/html;Charset=utf-8");
        try {
            PrintWriter writer = response.getWriter();
            String params = request.getParameter("callback");
            String json = JSONObject.toJSONString(map);
            writer.print(params+ "("+json+")");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/MD5AndKL.java
New file
@@ -0,0 +1,117 @@
package com.stylefeng.guns.modular.system.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.MessageDigest;
public class MD5AndKL {
    private static Logger logger = LoggerFactory.getLogger(MD5AndKL.class);
    /**
     * MD5加码。32位
     *
     * @param inStr
     * @return
     */
    public static String MD5(String inStr) {
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
        } catch (Exception e) {
            throw new RuntimeException(e.toString());
        }
        byte[] md5Bytes = md5.digest(inStr.getBytes());
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
    /**
     * 可逆的加密算法
     *
     * @param inStr
     * @return
     */
    public static String KL(String inStr) {
        char[] a = inStr.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 't');
        }
        String s = new String(a);
        return s;
    }
    /**
     * 加密后解密
     *
     * @param inStr
     * @return
     */
    public static String JM(String inStr) {
        char[] a = inStr.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 't');
        }
        String k = new String(a);
        return k;
    }
    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));
        return resultSb.toString();
    }
    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }
    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname)){
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            }else{
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return resultString;
    }
    private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5",
            "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
    public static void main(String args[]) {
        logger.debug("MD5后再加密:" + KL(MD5("123456")));
        logger.debug(MD5("123456"));
        // logger.debug("加密:" + KL(MD5("123456")));
        // s = KL(s);
        // logger.debug("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
        // logger.debug("解密:" + JM(KL(s)));
        // logger.debug("解密为MD5后的:" + KL(KL(MD5(s))));
        // logger.debug(JM("5d62957bb57d3e49dcf48a0df064be4c"));
        // logger.debug(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/QRCode/QRCodeUtils.java
New file
@@ -0,0 +1,268 @@
package com.stylefeng.guns.modular.system.util.QRCode;
import com.google.zxing.*;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import java.util.Hashtable;
import java.util.Random;
/**
 * 二维码工具类
 */
public class QRCodeUtils {
    private static Logger logger = LoggerFactory.getLogger(QRCodeUtils.class);
    private static final String CHARSET = "utf-8";
    private static final String FORMAT_NAME = "JPG";
    // 二维码尺寸
    private static final int QRCODE_SIZE = 300;
    // LOGO宽度
    private static final int WIDTH = 60;
    // LOGO高度
    private static final int HEIGHT = 60;
    private static BufferedImage createImage(String content, String imgPath,
                                             boolean needCompress) throws Exception {
        Hashtable<EncodeHintType, Object> hints = new Hashtable<EncodeHintType, Object>();
        hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        hints.put(EncodeHintType.CHARACTER_SET, CHARSET);
        hints.put(EncodeHintType.MARGIN, 1);
        BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
                BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
        int width = bitMatrix.getWidth();
        int height = bitMatrix.getHeight();
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000
                        : 0xFFFFFFFF);
            }
        }
        if (imgPath == null || "".equals(imgPath)) {
            return image;
        }
        // 插入图片
        QRCodeUtils.insertImage(image, imgPath, needCompress);
        return image;
    }
    /**
     * 插入LOGO
     *
     * @param source
     *            二维码图片
     * @param imgPath
     *            LOGO图片地址
     * @param needCompress
     *            是否压缩
     * @throws Exception
     */
    private static void insertImage(BufferedImage source, String imgPath,
                                    boolean needCompress) throws Exception {
        File file = new File(imgPath);
        if (!file.exists()) {
            logger.debug(""+imgPath+"   该文件不存在!");
            return;
        }
        Image src = ImageIO.read(new File(imgPath));
        int width = src.getWidth(null);
        int height = src.getHeight(null);
        if (needCompress) { // 压缩LOGO
            if (width > WIDTH) {
                width = WIDTH;
            }
            if (height > HEIGHT) {
                height = HEIGHT;
            }
            Image image = src.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            BufferedImage tag = new BufferedImage(width, height,
                    BufferedImage.TYPE_INT_RGB);
            Graphics g = tag.getGraphics();
            g.drawImage(image, 0, 0, null); // 绘制缩小后的图
            g.dispose();
            src = image;
        }
        // 插入LOGO
        Graphics2D graph = source.createGraphics();
        int x = (QRCODE_SIZE - width) / 2;
        int y = (QRCODE_SIZE - height) / 2;
        graph.drawImage(src, x, y, width, height, null);
        Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
        graph.setStroke(new BasicStroke(3f));
        graph.draw(shape);
        graph.dispose();
    }
    /**
     * 生成二维码(内嵌LOGO)
     *
     * @param content
     *            内容
     * @param imgPath
     *            LOGO地址
     * @param destPath
     *            存放目录
     * @param needCompress
     *            是否压缩LOGO
     * @throws Exception
     */
    public static String encode(String content, String imgPath, String destPath,
                                boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtils.createImage(content, imgPath,
                needCompress);
        mkdirs(destPath);
        String file = new Random().nextInt(99999999)+".jpg";
        ImageIO.write(image, FORMAT_NAME, new File(destPath+"/"+file));
        return file;
    }
    /**
     * 当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
     * @date 2013-12-11 上午10:16:36
     * @param destPath 存放目录
     */
    public static void mkdirs(String destPath) {
        File file =new File(destPath);
        //当文件夹不存在时,mkdirs会自动创建多层目录,区别于mkdir.(mkdir如果父目录不存在则会抛出异常)
        if (!file.exists() && !file.isDirectory()) {
            file.mkdirs();
        }
    }
    /**
     * 生成二维码(内嵌LOGO)
     *
     * @param content
     *            内容
     * @param imgPath
     *            LOGO地址
     * @param destPath
     *            存储地址
     * @throws Exception
     */
    public static void encode(String content, String imgPath, String destPath)
            throws Exception {
        QRCodeUtils.encode(content, imgPath, destPath, false);
    }
    /**
     * 生成二维码
     *
     * @param content
     *            内容
     * @param destPath
     *            存储地址
     * @param needCompress
     *            是否压缩LOGO
     * @throws Exception
     */
    public static void encode(String content, String destPath,
                              boolean needCompress) throws Exception {
        QRCodeUtils.encode(content, null, destPath, needCompress);
    }
    /**
     * 生成二维码
     *
     * @param content
     *            内容
     * @param destPath
     *            存储地址
     * @throws Exception
     */
    public static void encode(String content, String destPath) throws Exception {
        QRCodeUtils.encode(content, null, destPath, false);
    }
    /**
     * 生成二维码(内嵌LOGO)
     *
     * @param content
     *            内容
     * @param imgPath
     *            LOGO地址
     * @param output
     *            输出流
     * @param needCompress
     *            是否压缩LOGO
     * @throws Exception
     */
    public static void encode(String content, String imgPath,
                              OutputStream output, boolean needCompress) throws Exception {
        BufferedImage image = QRCodeUtils.createImage(content, imgPath,
                needCompress);
        ImageIO.write(image, FORMAT_NAME, output);
    }
    /**
     * 生成二维码
     *
     * @param content
     *            内容
     * @param output
     *            输出流
     * @throws Exception
     */
    public static void encode(String content, OutputStream output)
            throws Exception {
        QRCodeUtils.encode(content, null, output, false);
    }
    /**
     * 解析二维码
     *
     * @param file
     *            二维码图片
     * @return
     * @throws Exception
     */
    public static String decode(File file) throws Exception {
        BufferedImage image;
        image = ImageIO.read(file);
        if (image == null) {
            return null;
        }
        BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(
                image);
        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
        Result result;
        Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>();
        hints.put(DecodeHintType.CHARACTER_SET, CHARSET);
        result = new MultiFormatReader().decode(bitmap, hints);
        String resultStr = result.getText();
        return resultStr;
    }
    /**
     * 解析二维码
     *
     * @param path
     *            二维码图片地址
     * @return
     * @throws Exception
     */
    public static String decode(String path) throws Exception {
        return QRCodeUtils.decode(new File(path));
    }
    public static void main(String[] args) throws Exception {
        String text = "http://www.baidu.com";  //这里设置自定义网站url
        String logoPath = "C:\\Users\\admin\\Desktop\\test\\test.jpg";
        String destPath = "C:\\Users\\admin\\Desktop\\test\\";
        logger.debug(QRCodeUtils.encode(text, logoPath, destPath, true));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/RedisUtil.java
New file
@@ -0,0 +1,245 @@
package com.stylefeng.guns.modular.system.util;
import com.stylefeng.guns.core.util.ToolUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;
import java.io.IOException;
import java.util.*;
/**
 * Redis工具类
 */
@Component
public class RedisUtil {
    @Autowired
    private JedisPool jedisPool;
    private Timer timer;
    /**
     * 向redis中存储字符串没有过期时间
     * @param key
     * @param value
     */
    public void setStrValue(String key, String value){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
            Jedis resource = jedisPool.getResource();
            String set = resource.set(key, value);
            closeJedis(resource);
        }
    }
    /**
     * 以分钟为单位设置存储值(设置过期时间)
     * @param key
     * @param value
     * @param time 秒
     */
    public void setStrValue(String key, String value, int time){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(value)){
            Jedis resource = jedisPool.getResource();
            String setex = resource.setex(key, time, value);
            closeJedis(resource);
        }
    }
    /**
     * 从redis中获取值
     * @param key
     * @return
     */
    public String getValue(String key){
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            String data = resource.get(key);
            closeJedis(resource);
            return data;
        }
        return null;
    }
    /**
     * 批量获取
     * @param kes
     * @return
     */
    public List<Object> getValues(List<String> kes){
        if(null != kes){
            Jedis resource = jedisPool.getResource();
            Pipeline pipelined = resource.pipelined();
            for(String key : kes){
                pipelined.get(key);
            }
            List<Object> list = pipelined.syncAndReturnAll();
            closeJedis(resource);
            pipelined.clear();
            try {
                pipelined.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            List<Object> data = new ArrayList<>();
            for(Object o : list){
                if(null != o){
                    data.add(o);
                }
            }
            return data;
        }
        return null;
    }
    /**
     * 删除key
     * @param key
     */
    public void remove(String key){
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            Long del = resource.del(key);
            closeJedis(resource);
        }
    }
    /**
     * 向集合key添加数据
     * @param key
     * @param members
     */
    public void addSetValue(String key, String...members){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
            Jedis resource = jedisPool.getResource();
            Long sadd = resource.sadd(key, members);
            resource.close();
        }
    }
    /**
     * 返回Set集合数据
     * @param key
     * @return
     */
    public Set<String> getSetAllValue(String key){
        Set<String> smembers = new HashSet<>();
        if(ToolUtil.isNotEmpty(key)){
            Jedis resource = jedisPool.getResource();
            smembers = resource.smembers(key);
            resource.close();
        }
        return smembers;
    }
    /**
     * 删除Set集合中的值
     * @param key
     * @param members
     */
    public void delSetValue(String key, String...members){
        if(ToolUtil.isNotEmpty(key) && ToolUtil.isNotEmpty(members)){
            Jedis resource = jedisPool.getResource();
            Long sadd = resource.srem(key, members);
            resource.close();
        }
    }
    /**
     * 删除资源
     * @param jedis
     */
    public void closeJedis(Jedis jedis){
        if(null != jedis){
            jedis.close();
        }
    }
    /**
     * redis加锁
     * @param key
     * @param value
     * @param time
     * @return
     */
    public boolean lock(String key, String value, int time){
        if(!StringUtils.isEmpty(key)){
            key += "_lock";
            Jedis resource = jedisPool.getResource();
            String set = resource.set(key, value, "nx", "ex", time);
            if("OK".equals(set)){
                String finalKey = key;
                timer = new Timer();
                timer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        System.err.println("定时任务启动");
                        Jedis resource = jedisPool.getResource();
                        resource.setex(finalKey, time, value);
                        resource.close();
                    }
                }, 1000, 500);
            }
            resource.close();
            return "OK".equals(set) ? true : false;
        }
        return false;
    }
    /**
     * 获取redis锁
     * @param time
     * @return
     */
    public boolean lock(int time){
        String uuid = UUID.randomUUID().toString();
        return lock("redis", uuid, time);
    }
    public boolean lock(String key, int time){
        String uuid = UUID.randomUUID().toString();
        return lock(key, uuid, time);
    }
    /**
     * redis释放锁
     * @param key
     * @return
     */
    public boolean unlock(String key){
        if(!StringUtils.isEmpty(key)){
            key += "_lock";
            Jedis resource = jedisPool.getResource();
            timer.cancel();//取消定时任务
            Long del = resource.del(key);
            resource.close();
            return del != 0 ? true : false;
        }
        return false;
    }
    /**
     * 删除锁
     * @return
     */
    public boolean unlock(){
        return unlock("redis");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/ResultUtil.java
New file
@@ -0,0 +1,199 @@
package com.stylefeng.guns.modular.system.util;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
 * 定义统一返回对象
 */
@ApiModel(value = "统一返回结果集")
public class ResultUtil<T> {
    public static final Integer SUCCESS = 200;
    public static final Integer PARAM_ERROR = 300;
    public static final Integer RUNTIME_ERROR = 400;
    public static final Integer ERROR = 500;
    public static final Integer TOKEN_ERROR = 600;
    public static final Integer SIGN_ERROR = 700;
    public static final Integer TIP_MSG = 800;
    public static final String Token = "TOKEN_INVALID";
    public static final String SIGN = "SIGN_INVALID";
    @ApiModelProperty(name = "code", value = "业务状态码 200:成功,300:参数错误,400:运行异常,500:其他异常, 600:token无效,需重新登录,700:签名无效")
    private Integer code;//备用状态码
    @ApiModelProperty(name = "msg", value = "返回结果说明")
    private String msg;//返回说明
    @ApiModelProperty(name = "data", value = "返回结果值")
    private T data;//返回数据
    public String getMsg() {
        return msg;
    }
    public T getData() {
        return data;
    }
    public Integer getCode() {
        return code;
    }
    private ResultUtil(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    private ResultUtil(Integer code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }
    public static <T> ResultUtil<T> getResult(Integer code, String msg){
        return new ResultUtil<>(code, msg);
    }
    public static <T> ResultUtil<T> getResult(Integer code, String msg, T data){
        return new ResultUtil<>(code, msg, data);
    }
    /**
     * 错误信息
     * @return
     */
    public static ResultUtil error(String mag){
        return ResultUtil.getResult(ResultUtil.ERROR, mag, new Object());
    }
    /**
     * 错误信息
     * @return
     */
    public static <T> ResultUtil<T> error(String mag, T obj){
        return ResultUtil.getResult(ResultUtil.ERROR, mag, obj);
    }
    /**
     * token失效
     * @return
     */
    public static ResultUtil tokenErr(){
        return ResultUtil.getResult(ResultUtil.TOKEN_ERROR, ResultUtil.Token, new Object());
    }
    /**
     * token失效
     * @return
     */
    public static ResultUtil tokenErr(String msg){
        return ResultUtil.getResult(ResultUtil.TOKEN_ERROR, msg, new Object());
    }
    /**
     * 参数异常
     * @return
     */
    public static ResultUtil paranErr(){
        return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "PARAM_ERROR", new Object());
    }
    /**
     * 参数异常
     * @return
     */
    public static <T> ResultUtil<T> paranErr(T data){
        return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "SYSTEM_RUN_ERROR", data);
    }
    /**
     * 运行异常
     * @return
     */
    public static ResultUtil runErr(){
        return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, "SYSTEM_RUN_ERROR", new Object());
    }
    /**
     * 运行异常
     * @return
     */
    public static <T> ResultUtil<T> runErr(T data){
        return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, "SYSTEM_RUN_ERROR", data);
    }
    /**
     * 运行异常
     * @return
     */
    public static <T> ResultUtil<T> runErr(T data, String msg){
        return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, msg, data);
    }
    /**
     * 返回成功
     * @param
     * @return
     */
    public static ResultUtil success(){
        return ResultUtil.getResult(ResultUtil.SUCCESS, "SUCCESS", new Object());
    }
    /**
     * 返回成功
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultUtil<T> success(T data){
        return ResultUtil.getResult(ResultUtil.SUCCESS, "SUCCESS", data);
    }
    /**
     * 返回成功
     * @param msg
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultUtil<T> success(String msg, T data){
        return ResultUtil.getResult(ResultUtil.SUCCESS, msg, data);
    }
    /**
     * 签名无效
     * @param <T>
     * @return
     */
    public static <T> ResultUtil<T> sign(){
        return ResultUtil.getResult(ResultUtil.SIGN_ERROR, SIGN);
    }
    /**
     * 提示内容
     * @param tip
     * @param <T>
     * @return
     */
    public static <T> ResultUtil<T> tip(String tip){
        return ResultUtil.getResult(ResultUtil.TIP_MSG, tip);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SinataUtil.java
New file
@@ -0,0 +1,388 @@
package com.stylefeng.guns.modular.system.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * 基本数据处理工具类
 */
public class SinataUtil {
    private static Logger logger = LoggerFactory.getLogger(SinataUtil.class);
    /**
     * List集合分页<br/>
     * 创建人:Mryang<br/>
     * 时间:2016年7月28日-下午2:58:14 <br/>
     * @param <T>
     * @param pageNo
     * @param pageSize
     * @param list
     * @throws Exception List<UserOrderList> <br/>
     */
    public static <T> List<T> listpage(int pageNo, int pageSize, List<T> list) throws Exception {
        List<T> result = new ArrayList<T>();
        if (list != null && list.size() > 0) {
            int allCount = list.size();
            if(pageNo > 1 && allCount < pageSize) {
                return new ArrayList<>();
            }
            int pageCount = (allCount + pageSize - 1) / pageSize;
            if (pageNo >= pageCount) {
                pageNo = pageCount;
            }
            int start = (pageNo - 1) * pageSize;
            int end = pageNo * pageSize;
            if (end >= allCount) {
                end = allCount;
            }
            for (int i = start; i < end; i++) {
                result.add(list.get(i));
            }
        }
        return (result != null && result.size() > 0) ? result : new ArrayList<T>();
    }
    /**
     * Double类型取整
     * @param num
     * @return
     */
    public static String doubleTrans(double num) {
        return String.valueOf((long) num);
    }
    /**
     * Double类型保留1位小数
     *
     * @param num
     * @return
     */
    public static String doubleRetainOne(double num) {
        DecimalFormat dfs = new DecimalFormat("0.0");
        return dfs.format(num);
    }
    /**
     * 5位随机数
     * @return
     */
    public static synchronized String getFive() {
        int i=(int)((Math.random()*9+1)*10000);
        return i+"";
    }
    /**
     * Double类型保留2位小数
     *
     * @param num
     * @return
     */
    public static String doubleRetainTwo(double num) {
        DecimalFormat dfs = new DecimalFormat("0.00");
        String.format("%.2f", num);
        return dfs.format(num);
    }
    /**
     * Double类型保留1位小数(四舍五入)
     *
     * @param num
     * @return
     */
    public static String doubleForwardOne(double num) {
        return String.format("%.1f", num);
    }
    /**
     * Double类型保留2位小数(四舍五入)
     *
     * @param num
     * @return
     */
    public static String doubleForwardTwo(double num) {
        return String.format("%.2f", num);
    }
    /**
     * 字符串转换成Ascii
     *
     * @param value
     * @return
     */
    public static String stringToAscii(String value) {
        StringBuffer sbu = new StringBuffer();
        char[] chars = value.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (i != chars.length - 1) {
                sbu.append((int) chars[i]);
            } else {
                sbu.append((int) chars[i]);
            }
        }
        return sbu.toString();
    }
    /**
     * 小数转换为百分比
     *
     * @param decimal
     * @return
     * @author TaoNingBo
     */
    public static String decTurnPercent(double decimal) {
        NumberFormat num = NumberFormat.getPercentInstance();
        num.setMaximumIntegerDigits(3);
        num.setMaximumFractionDigits(2);
        return num.format(decimal);
    }
    /**
     * Ascii转换成字符串
     *
     * @param value
     * @return
     */
    public static String asciiToString(String value) {
        String[] chars = value.split(",");
        StringBuffer sbu = new StringBuffer();
        for (int i = 0; i < chars.length; i++) {
            sbu.append((char) Integer.parseInt(chars[i]));
        }
        return sbu.toString();
    }
    /**
     * 字符串转换unicode
     *
     * @param string
     * @return
     * @author TaoNingBo
     */
    public static String string2Unicode(String string) {
        StringBuffer unicode = new StringBuffer();
        for (int i = 0; i < string.length(); i++) {
            // 取出每一个字符
            char c = string.charAt(i);
            // 转换为unicode
            unicode.append("\\u" + Integer.toHexString(c));
        }
        return unicode.toString();
    }
    /**
     * unicode 转字符串
     *
     * @param unicode
     * @return
     * @author TaoNingBo
     */
    public static String unicode2String(String unicode) {
        StringBuffer string = new StringBuffer();
        String[] hex = unicode.split("\\\\u");
        for (int i = 1; i < hex.length; i++) {
            // 转换出每一个代码点
            int data = Integer.parseInt(hex[i], 16);
            // 追加成string
            string.append((char) data);
        }
        return string.toString();
    }
    /**
     * 字符串编码转换的实现方法
     *
     * @param str
     *            待转换编码的字符串
     * @param newCharset
     *            目标编码
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String changeCharset(String str, String newCharset) throws UnsupportedEncodingException {
        if (str != null) {
            // 用默认字符编码解码字符串。
            byte[] bs = str.getBytes();
            // 用新的字符编码生成字符串
            return new String(bs, newCharset);
        }
        return null;
    }
    /**
     * 注: \n 回车( ) \t 水平制表符( ) \s 空格(\u0008) \r 换行( )
     *
     * @param str
     * @return
     */
    public static String replaceBlank(String str) {
        String dest = "";
        if (str != null) {
            Pattern p = Pattern.compile("\\s*|\t|\r|\n");
            Matcher m = p.matcher(str);
            dest = m.replaceAll("");
        }
        return dest;
    }
    /**
     * 判断该字符串不能为空
     *
     * @param str
     * @return
     * @author TaoNingBo
     */
    public static boolean isNotEmpty(Object str) {
        return !isEmpty(str);
    }
    public static boolean isNotEmptyUndefined(Object str) {
        return !isEmpty(str) && !str.toString().equals("undefined");
    }
    /**
     * 字符串编码转换的实现方法
     *
     * @param str
     *            待转换编码的字符串
     * @param oldCharset
     *            原编码
     * @param newCharset
     *            目标编码
     * @return
     * @throws UnsupportedEncodingException
     */
    public static String changeCharset(String str, String oldCharset, String newCharset) throws UnsupportedEncodingException {
        if (str != null) {
            // 用旧的字符编码解码字符串。解码可能会出现异常。
            byte[] bs = str.getBytes(oldCharset);
            // 用新的字符编码生成字符串
            return new String(bs, newCharset);
        }
        return null;
    }
    /**
     * 给手机号码加分割符
     *
     * @param phone
     * @return
     * @author TaoNingBo
     */
    public static String splitPhone(String phone) {
        if (isNotEmpty(phone)) {
            String strone = phone.substring(0, 3);
            String strtwo = phone.substring(strone.length(), 7);
            String strthree = phone.substring(strtwo.length() + strone.length(), phone.length());
            return strone + "-" + strtwo + "-" + strthree;
        }
        return "";
    }
    /**
     * 非空判断
     *
     * @param str
     * @return
     * @author TaoNingBo
     */
    public static boolean isEmpty(Object str) {
        return str == null || str.toString().length() == 0 || str.equals("") || str.toString().matches("\\s*");
    }
    /**
     * 将List<{@link Object}>转换成List<{@link T}>
     *
     * @param list
     *            将要转换的对象
     * @param clazs
     *            需要转换的泛型对象
     * @return
     * @author TaoNingBo
     */
    @SuppressWarnings("unchecked")
    public static <T> List<T> fromToObject(List<?> list, Class<T> clazs) {
        List<T> t = new ArrayList<T>();
        for (Object object : list) {
            t.add((T) object);
        }
        return t;
    }
     /**
     * 生成 uuid, 即用来标识一笔单,也用做 nonce_str
     * @return
     */
    public static String generateUUID() {
        return UUID.randomUUID().toString().replaceAll("-", "").substring(0, 32);
    }
    /**
     * 将List<{@link Object}>转换成List<{@link Map<String, Object>}>
     *
     * @param list
     * @return
     * @author TaoNingBo
     */
    @SuppressWarnings("unchecked")
    public static List<Map<String, Object>> fromToObject_M(List<?> list) {
        List<Map<String, Object>> t = new ArrayList<Map<String, Object>>();
        for (Object object : list) {
            t.add((Map<String, Object>) object);
        }
        return t;
    }
    /**
     * URL编码
     *
     * @param url
     * @return
     */
    @SuppressWarnings("deprecation")
    public static String URLEncode(String url) {
        try {
            return URLEncoder.encode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return URLEncoder.encode(url);
    }
    /**
     * URL解码
     *
     * @param url
     * @return
     */
    @SuppressWarnings("deprecation")
    public static String URLDecode(String url) {
        try {
            return URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return URLDecoder.decode(url);
    }
    public static void main(String[] args) throws ParseException {
        logger.debug(doubleRetainTwo(0.0));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SmsUtil.java
New file
@@ -0,0 +1,77 @@
package com.stylefeng.guns.modular.system.util;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
@Component
public class SmsUtil {
    private static Logger logger = LoggerFactory.getLogger(SmsUtil.class);
    public static void main(String[] args) {
        //短信下发
        String sendUrl = "https://xxx/msg/send/json";
        Map map = new HashMap();
        map.put("account","N*******");//API账号
        map.put("password","************");//API密码
        map.put("msg","您本次验证码为:{0}。请勿泄露他人,如非本人操作可勿略本短信");//短信内容
        map.put("phone","15300000000");//手机号
        map.put("report","true");//是否需要状态报告
        map.put("extend","123");//自定义扩展码
        JSONObject js = (JSONObject) JSONObject.toJSON(map);
        logger.debug(sendSmsByPost(sendUrl,js.toString()));
        //查询余额
        String balanceUrl = "https://xxx/msg/balance/json";
        Map map1 = new HashMap();
        map1.put("account","N*******");
        map1.put("password","************");
        JSONObject js1 = (JSONObject) JSONObject.toJSON(map1);
        logger.debug(sendSmsByPost(balanceUrl,js1.toString()));
    }
    public static String sendSmsByPost(String path, String postContent) {
        URL url = null;
        try {
            url = new URL(path);
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setConnectTimeout(10000);
            httpURLConnection.setReadTimeout(10000);
            httpURLConnection.setDoOutput(true);
            httpURLConnection.setDoInput(true);
            httpURLConnection.setRequestProperty("Charset", "UTF-8");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");
            httpURLConnection.connect();
            OutputStream os=httpURLConnection.getOutputStream();
            os.write(postContent.getBytes("UTF-8"));
            os.flush();
            StringBuilder sb = new StringBuilder();
            int httpRspCode = httpURLConnection.getResponseCode();
            if (httpRspCode == HttpURLConnection.HTTP_OK) {
                BufferedReader br = new BufferedReader(
                        new InputStreamReader(httpURLConnection.getInputStream(), "utf-8"));
                String line = null;
                while ((line = br.readLine()) != null) {
                    sb.append(line);
                }
                br.close();
                return sb.toString();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SpringUtil.java
New file
@@ -0,0 +1,34 @@
package com.stylefeng.guns.modular.system.util;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
    @Autowired
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContextParam) throws BeansException {
        applicationContext = applicationContextParam;
    }
    public static Object getObject(String id) {
        Object object = null;
        object = applicationContext.getBean(id);
        return object;
    }
    public static <T> T getObject(Class<T> tClass) {
        return applicationContext.getBean(tClass);
    }
    public static Object getBean(String tClass) {
        return applicationContext.getBean(tClass);
    }
    public <T> T getBean(Class<T> tClass) {
        return applicationContext.getBean(tClass);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/SysException.java
New file
@@ -0,0 +1,16 @@
package com.stylefeng.guns.modular.system.util;
import lombok.Data;
/**
 * 系统异常类型
 */
@Data
public class SysException extends Exception {
    public SysException(String msg){
        super(msg);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/TencentMapUtil.java
New file
@@ -0,0 +1,44 @@
package com.stylefeng.guns.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 腾讯地图api工具类型
* @author pzb
* @Date 2021/12/27 11:37
*/
@Component
public class TencentMapUtil {
    private final String key = "";
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 坐标转换
     * @param locations 纬度前,经度后,纬度和经度之间用",“分隔,每组坐标之间使用”;"分隔;
     * @param type      1 GPS坐标 2 sogou经纬度 3 baidu经纬度 4 mapbar经纬度 5 [默认]腾讯、google、高德坐标 6 sogou墨卡托
     * @return
     */
    public ResultUtil translate(String locations, Integer type) throws Exception{
        String url = "https://apis.map.qq.com/ws/coord/v1/translate?locations=" + locations + "&type=" + type + "&key=" + key;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        if(httpResult.getCode() == 200){
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            if(jsonObject.getInteger("status") == 0){
                JSONObject locations1 = jsonObject.getJSONArray("locations").getJSONObject(0);
                return ResultUtil.success(locations1.getString("lng") + "," + locations1.getString("lat"));
            }else{
                return ResultUtil.error(jsonObject.getString("message"));
            }
        }
        return ResultUtil.error(httpResult.getData());
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/UUIDUtil.java
New file
@@ -0,0 +1,101 @@
package com.stylefeng.guns.modular.system.util;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
/**
 * 定义生成随机码的工具类
 */
public class UUIDUtil {
    private int i = 1;
    /**
     * 定义生成原生的UUID随机码
     * @return
     */
    public synchronized static String getNativeUUID(){
        return UUID.randomUUID().toString();
    }
    /**
     * 生成32位随机码
     * @return
     */
    public synchronized static String getRandomCode(){
        return UUIDUtil.getNativeUUID().replaceAll("-", "");
    }
    /**
     * 获取给定长度的随机码
     * @param num
     * @return
     * @throws Exception
     */
    public synchronized static String getRandomCode(Integer num) throws Exception{
        String str = null;
        if(0 < num){
            if(num % 32 > 0){
                Integer s = num / 32;
                Integer l = num % 32;
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < s; i++){
                    sb.append(UUIDUtil.getRandomCode());
                }
                sb.append(UUIDUtil.getRandomCode().substring(0, l));
                str = sb.toString();
            }else if(num % 32 == 0){
                Integer s = num / 32;
                StringBuffer sb = new StringBuffer();
                for(int i = 0; i < s; i++){
                    sb.append(UUIDUtil.getRandomCode());
                }
                str = sb.toString();
            }else{
                str = UUIDUtil.getRandomCode().substring(0, num);
            }
        }else{
            throw new Exception("参数只能大于0");
        }
        return str;
    }
    /**
     * 获取根据当前时间的字符串数据
     * @return
     */
    public synchronized static String getTimeStr(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddhhmmssSSS");
        return simpleDateFormat.format(new Date());
    }
    /**
     * @Description: 获取数字随机码
     * @Author pzb
     * @Date 2021/8/11 16:52
     * @Param
     * @Return
     * @Exception
     */
    public synchronized static String getNumberRandom(Integer num){
        if(null == num){
            num = 32;
        }
        StringBuffer sb = new StringBuffer();
        for(int i = 0; i < num; i++){
            sb.append(Double.valueOf(Math.random() * 10).intValue());
        }
        return sb.toString();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthIntercepter.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.modular.system.util.auth;
import com.alibaba.fastjson.JSON;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@Component
public class AuthIntercepter implements HandlerInterceptor {
    @Autowired
    AuthService authService;
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws IOException {
        String appid = req.getParameter("appid");
        String sign = req.getParameter("sign");
        ResultUtil resultUtil = authService.checkSyncAuth(appid, sign, req);
        if (resultUtil.getCode() != 200) {
            res.setStatus(HttpStatus.OK.value());
            res.setHeader("Content-type", "text/html;charset=UTF-8");
            res.getWriter().print(JSON.toJSONString(resultUtil));//Res.Failure("req timeout, please try again")
            return false;
        }
        return true;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthService.java
New file
@@ -0,0 +1,51 @@
package com.stylefeng.guns.modular.system.util.auth;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
@Service
public class AuthService {
    public static final AuthService me = new AuthService();
    /**
     * 鉴权
     * @param appid
     * @param sign
     * @param requset
     * @return
     */
    public ResultUtil checkSyncAuth(String appid, String sign, HttpServletRequest requset) {
        try {
            String contentType = requset.getContentType();
            if(contentType.equals("application/json")){//不校验json方式提交
                return ResultUtil.success();
            }
            if (StringUtils.isBlank(sign)) {
                return ResultUtil.sign();
            }
            // 1.鉴权
            String signUrl = AuthenticationKit.getSignUrl(requset, "sign");
            signUrl = signUrl.replaceAll("& #40;", "\\(");
            signUrl = signUrl.replaceAll("& #41;", "\\)");
            String signUrlEncode = AuthenticationKit.signUrlEncode(signUrl, appid);
            if(sign.indexOf(" ") != -1 && signUrlEncode.indexOf("+") != -1){//处理前后端加密差异
                signUrlEncode = signUrlEncode.replaceAll("\\+", " ");
            }
            // 签名无
            if (StringUtils.isBlank(sign) || !sign.equals(signUrlEncode)) {
                return ResultUtil.sign();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.runErr();
        }
        return ResultUtil.success();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/AuthenticationKit.java
New file
@@ -0,0 +1,259 @@
package com.stylefeng.guns.modular.system.util.auth;
import org.apache.tomcat.util.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
 *
 * 接口鉴权工具类
 *
 * @author gwx 2017-12-23
 *
 */
public class AuthenticationKit {
    private static Logger logger = LoggerFactory.getLogger(AuthenticationKit.class);
    public static final String utf8="UTF-8";
    /**
     * 返回64 位 token
     *
     * @param key 自定义安全字符
     * @return
     * @throws Exception
     */
    public static String getToken(String key) throws Exception {
        // 随机生成 32位字符
        String salt = HashKit.generateSaltForSha256();
        // 获取当前时间
        long cur = System.currentTimeMillis();
        // 生成64位token
        String access_token = getToken256(key, salt, cur);
        return access_token;
    }
    /**
     * 返回64 位 token
     *
     * @param key
     * @return
     * @throws Exception
     */
    public static String getToken256(String key, String salt, long cur) throws Exception {
        // 生成64位token
        String access_token = HashKit.sha256(salt + cur + key);
        return access_token;
    }
    /**
     * 返回到秒
     *
     * @return
     */
    public static String createTimestamp() {
        long l = System.currentTimeMillis();
        return Long.toString(l / 1000);
    }
    /**
     * 返回noce 不带 短杠"-"
     *
     * @return
     */
    public static String createNonceStr() {
        return getUUID();
    }
    public static String getUUID() {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        str = str.replaceAll("-", "");
        return str;
    }
    /**
     * 组装路径
     *
     * @param params
     * @return
     */
    public static String localSignParam(Map<String, String> params) {
        return localSignUrl(null, params, false);
    }
    /**
     * 组装签名路径
     * @param url
     * @param params
     * @return
     */
    public static String localSignUrl(String url, Map<String, String> params, boolean urlEncode) {
        Set<Map.Entry<String, String>> entries = params.entrySet();
        List<Map.Entry<String, String>> infoIds = new ArrayList<Map.Entry<String, String>>(entries);
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return (o1.getKey()).toString().compareTo(o2.getKey());
            }
        });
        // 构造签名键值对的格式
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> item : infoIds) {
            if (item.getKey() != null || item.getKey() != "") {
                String key = item.getKey();
                Object val = item.getValue();
                if (!(val == "" || val == null)) {
                    sb.append(key + "=" + val + "&");
                }
            }
        }
        String substring = sb.substring(0, sb.length() - 1);
        return substring;
    }
    /**
     * 加密签名路径生成签名
     *
     * @param signUrl
     *            /token?appid=12345&timestamp=1512440267&nonce=12345
     * @param encryptKey
     * @return
     * @throws Exception
     */
    public static String signUrlEncode(String signUrl, String encryptKey) throws Exception {
        byte[] signByte = HMACSHA1.HmacSHA1Encrypt(signUrl, encryptKey);
        String localSign = Base64.encodeBase64String(signByte);
        return localSign;
    }
    public static void main(String[] ager){
        try {
            String appid = "b653c558d5bd448e";
            Map<String, Object> params = new HashMap<>();
            params.put("openid", "oRQiP5KETmhrVAZaCb8US5WRpR2I");
            params.put("priTmplId", "W13RI0WjjgxEhmFqAtZJfouFyUgawAqm8eMfI6oy2_4");
            params.put("appid", appid);
            Set<Map.Entry<String, Object>> entries = params.entrySet();
            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(entries);
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序(字典序)
            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造签名键值对的格式
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, Object> item : infoIds) {
                if (item.getKey() != null || item.getKey() != "") {
                    String key = item.getKey();
                    Object val = item.getValue();
                    if (!(val == "" || val == null)) {
                        sb.append(key + "=" + val + "&");
                    }
                }
            }
            String substring = sb.substring(0, sb.length() - 1);
            String s = AuthenticationKit.signUrlEncode(substring, appid);
            logger.debug(s);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 返回鉴权 签名路径
     *
     * @param req
     * @return
     */
    public static String getSignUrl(HttpServletRequest req) {
        return getSignUrl(req,"");
    }
    /**
     * 服务端 获取 客户端请求 组装验证签名
     * @param req
     * @param delParams 移除不相关 的签名参数
     * @return
     */
    public static String getSignUrl(HttpServletRequest req, String... delParams) {
        // 获取相对的访问路径
        String url = req.getServletPath();
        Map<String, String> paramMap = packageRequestGetParams(req);
        if (paramMap.size() > 0) {
            // 删除
            for (int i = 0, len = delParams.length; i < len; i++) {
                paramMap.remove(delParams[i]);
            }
            return localSignUrl(url, paramMap, false);
        }
        return null;
    }
    /**
     * 组装签名路径 客户端测试用
     * @param url api访问地址 "
     * @param appid
     * @return
     */
    public static String getSignUrl(String url, String appid, Map<String, String> queryParas) {
        Map<String, String> params = new TreeMap<String, String>();
        params.put("appid", appid);
        params.put("nonce", createNonceStr());
        params.put("timestamp", createTimestamp());
        if(queryParas!=null && queryParas.size()>0){
            params.putAll(queryParas);
        }
        return localSignUrl(url, params, false);
    }
    /**
     * 组装签名路径 客户端测试用
     * @param url api访问地址
     * @param appid
     * @return
     */
    public static String getSignUrl(String url, String appid) {
        return getSignUrl(url, appid, "");
    }
    /**
     *
     * @param url
     * @param appid
     * @param params
     * @return
     */
    public static String getSignUrl(String url, String appid, String params) {
        String urlTmp = getSignUrl(url, appid, new HashMap<String,String>());
        return urlTmp + UrlEncoderUtils.encode(params);
    }
    /**
     * 解析get参数返回treemap
     * @param req
     * @return
     */
    public static Map<String, String> packageRequestGetParams(
            HttpServletRequest req) {
        Map<String, String> paramMap = new TreeMap<String, String>();
        Enumeration pNames = req.getParameterNames();
        while (pNames.hasMoreElements()) {
            String key = (String) pNames.nextElement();
            String value = req.getParameter(key);
            paramMap.put(key, value);
        }
        return paramMap;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/Configuration.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.util.auth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Component
public class Configuration implements WebMvcConfigurer {
    @Autowired
    private AuthIntercepter authIntercepter;
    /**
     * 重写添加拦截器方法并添加配置拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(authIntercepter).addPathPatterns("/api/**")
                .excludePathPatterns("/base/**");
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/HMACSHA1.java
New file
@@ -0,0 +1,63 @@
package com.stylefeng.guns.modular.system.util.auth;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class HMACSHA1 {
    private static final String MAC_NAME = "HmacSHA1";
    private static final String ENCODING = "UTF-8";
    /*
     * 展示了一个生成指定算法密钥的过程 初始化HMAC密钥
     *
     * @return
     *
     * @throws Exception
     *
     * public static String initMacKey() throws Exception { //得到一个 指定算法密钥的密钥生成器
     * KeyGenerator KeyGenerator keyGenerator
     * =KeyGenerator.getInstance(MAC_NAME); //生成一个密钥 SecretKey secretKey
     * =keyGenerator.generateKey(); return null; }
     */
    /**
     * 使用 HMAC-SHA1 签名方法对对encryptText进行签名
     *
     * @param encryptText
     *            被签名的字符串
     * @param encryptKey
     *            密钥
     * @return
     * @throws Exception
     */
    public static byte[] HmacSHA1Encrypt(String encryptText, String encryptKey) throws Exception {
        byte[] data = encryptKey.getBytes(ENCODING);
        // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        Mac mac = Mac.getInstance(MAC_NAME);
        SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
        // 生成一个指定 Mac 算法 的 Mac 对象
        // 用给定密钥初始化 Mac 对象
        mac.init(secretKey);
        byte[] text = encryptText.getBytes(ENCODING);
        // 完成 Mac 操作
        return mac.doFinal(text);
    }
    public static void main(String[] args) {
        String encryptText = "123";
        String encryptKey = "adc";
        try {
            byte[] b = HmacSHA1Encrypt(encryptText, encryptKey);
            String str = HashKit.toHex(b);
            String str2 = new String(Base64.encodeBase64(b));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/HashKit.java
New file
@@ -0,0 +1,109 @@
package com.stylefeng.guns.modular.system.util.auth;
/**
 * Copyright (c) 2011-2017, James Zhan 詹波 (jfinal@126.com).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import java.security.MessageDigest;
public class HashKit {
    public static final long FNV_OFFSET_BASIS_64 = 0xcbf29ce484222325L;
    public static final long FNV_PRIME_64 = 0x100000001b3L;
    private static final java.security.SecureRandom random = new java.security.SecureRandom();
    private static final char[] HEX_DIGITS = "0123456789abcdef".toCharArray();
    private static final char[] CHAR_ARRAY = "_-0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
            .toCharArray();
    public static long fnv1a64(String key) {
        long hash = FNV_OFFSET_BASIS_64;
        for (int i = 0, size = key.length(); i < size; i++) {
            hash ^= key.charAt(i);
            hash *= FNV_PRIME_64;
        }
        return hash;
    }
    public static String md5(String srcStr) {
        return hash("MD5", srcStr);
    }
    public static String sha1(String srcStr) {
        return hash("SHA-1", srcStr);
    }
    public static String sha256(String srcStr) {
        return hash("SHA-256", srcStr);
    }
    public static String sha384(String srcStr) {
        return hash("SHA-384", srcStr);
    }
    public static String sha512(String srcStr) {
        return hash("SHA-512", srcStr);
    }
    public static String hash(String algorithm, String srcStr) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);
            byte[] bytes = md.digest(srcStr.getBytes("utf-8"));
            return toHex(bytes);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    public static String toHex(byte[] bytes) {
        StringBuilder ret = new StringBuilder(bytes.length * 2);
        for (int i = 0; i < bytes.length; i++) {
            ret.append(HEX_DIGITS[(bytes[i] >> 4) & 0x0f]);
            ret.append(HEX_DIGITS[bytes[i] & 0x0f]);
        }
        return ret.toString();
    }
    /**
     * md5 128bit 16bytes sha1 160bit 20bytes sha256 256bit 32bytes sha384
     * 384bit 48bytes sha512 512bit 64bytes
     */
    public static String generateSalt(int saltLength) {
        StringBuilder salt = new StringBuilder(saltLength);
        for (int i = 0; i < saltLength; i++) {
            salt.append(CHAR_ARRAY[random.nextInt(CHAR_ARRAY.length)]);
        }
        return salt.toString();
    }
    public static String generateSaltForSha256() {
        return generateSalt(32);
    }
    public static String generateSaltForSha512() {
        return generateSalt(64);
    }
    public static boolean slowEquals(byte[] a, byte[] b) {
        if (a == null || b == null) {
            return false;
        }
        int diff = a.length ^ b.length;
        for (int i = 0; i < a.length && i < b.length; i++) {
            diff |= a[i] ^ b[i];
        }
        return diff == 0;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/auth/UrlEncoderUtils.java
New file
@@ -0,0 +1,47 @@
package com.stylefeng.guns.modular.system.util.auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class UrlEncoderUtils {
    private static Logger logger = LoggerFactory.getLogger(UrlEncoderUtils.class);
    private static final String PATH_DELIMITER = "/";
    public static String encode(String originUrl) {
        try {
            return URLEncoder.encode(originUrl, "UTF-8").replace("+", "%20").replace("*", "%2A")
                    .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            logger.debug("URLEncoder error, encode utf8, exception: {}");
        }
        return null;
    }
    // encode路径, 不包括分隔符
    public static String encodeEscapeDelimiter(String urlPath) {
        StringBuilder pathBuilder = new StringBuilder();
        String[] pathSegmentsArr = urlPath.split(PATH_DELIMITER);
        boolean isFirstSegMent = true;
        for (String pathSegment : pathSegmentsArr) {
            if (isFirstSegMent) {
                pathBuilder.append(encode(pathSegment));
                isFirstSegMent = false;
            } else {
                pathBuilder.append(PATH_DELIMITER).append(encode(pathSegment));
            }
        }
        if (urlPath.endsWith(PATH_DELIMITER)) {
            pathBuilder.append(PATH_DELIMITER);
        }
        return pathBuilder.toString();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/httpClinet/HttpClientUtil.java
New file
@@ -0,0 +1,297 @@
package com.stylefeng.guns.modular.system.util.httpClinet;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.stylefeng.guns.modular.system.util.UUIDUtil;
import com.stylefeng.guns.modular.system.util.auth.UrlEncoderUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
/**
 * http工具类
 */
@Component
public class HttpClientUtil {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
    private PoolingHttpClientConnectionManager connectionManager;
    public HttpClientUtil(){
        //1.创建连接池管理器
        connectionManager = new PoolingHttpClientConnectionManager(60000,
                TimeUnit.MILLISECONDS);
        connectionManager.setMaxTotal(1000);
        connectionManager.setDefaultMaxPerRoute(50);
    }
    /**
     * 创建一个httpClient对象
     */
    private CloseableHttpClient getHttpCline(){
        return  HttpClients.custom()
                .setConnectionManager(connectionManager)
                .disableAutomaticRetries()
                .build();
    }
    private RequestConfig getRequestConfig(){
        RequestConfig.Builder builder = RequestConfig.custom();
        builder.setSocketTimeout(60000)//3.1设置客户端等待服务端返回数据的超时时间
                .setConnectTimeout(30000)//3.2设置客户端发起TCP连接请求的超时时间
                .setExpectContinueEnabled(true)
                .setConnectionRequestTimeout(30000);//3.3设置客户端从连接池获取链接的超时时间
        return builder.build();
    }
    /**
     * 创建一个POST请求实例
     * @param url       请求地址
     * @param params    请求参数
     */
    private CloseableHttpResponse setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.getRequestConfig());
        if(null != header){
            for(String key : header.keySet()){
                httpPost.setHeader(key, header.get(key));
            }
        }
        List<NameValuePair> list = new ArrayList<>();
        if(null != params){
            Set<String> keys = params.keySet();
            for(String key : keys){
                list.add(new BasicNameValuePair(key, null == params.get(key) ? null : params.get(key).toString()));
            }
        }
        switch (contentType){
            case "form":
                httpPost.setEntity(new UrlEncodedFormEntity(list, "UTF-8"));
                break;
            case "json":
                ObjectMapper objectMapper = new ObjectMapper();
                String s =objectMapper.writeValueAsString(params);
                httpPost.setEntity(new StringEntity(s, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Charset.forName("UTF-8"))));
                break;
        }
        return getHttpCline().execute(httpPost);
    }
    /**
     * 获取get请求实例
     * @param url       请求地址
     * @param params    请求参数
     */
    private CloseableHttpResponse setGetHttpRequset(String url, Map<String, Object> params, Map<String, String> header) throws Exception{
        StringBuffer sb = new StringBuffer();
        String p = "";
        if(null != params){
            Set<String> keys = params.keySet();
            for(String key : keys){
                sb.append(key + "=" + params.get(key) + "&");
            }
            p = "?" + sb.substring(0, sb.length() - 1);
        }
        HttpGet httpGet = new HttpGet(url + p);
        httpGet.setConfig(getRequestConfig());
        if(null != header){
            for(String key : header.keySet()){
                httpGet.setHeader(key, header.get(key));
            }
        }
        return getHttpCline().execute(httpGet);
    }
    /**
     * 发送http请求
     * @param mothed        "GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS"
     * @param url           请求地址
     * @param params        请求参数
     * @param header        请求头
     * @param contentType   参数请求方式form/json
     * @return
     */
    public HttpResult pushHttpRequset(String mothed, String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{
        String randome = UUID.randomUUID().toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
        logger.info(sdf.format(new Date()) + "----(" + randome + ")请求参数:" + JSON.toJSONString(params));
        CloseableHttpResponse httpResponse = null;
        switch (mothed){
            case "GET":
                httpResponse = this.setGetHttpRequset(url, params, header);
                break;
            case "POST":
                httpResponse = setPostHttpRequset(url, params, header, contentType);
                break;
        }
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        logger.info(sdf.format(new Date()) + "----(" + randome + ")返回结果:" + content);
        HttpResult httpResult = HttpResult.getHttpResult(statusCode, content);
        this.close(httpResponse);
        return httpResult;
    }
    public HttpResult pushJsonRequset(String url, String json) throws Exception{
        String randome = UUID.randomUUID().toString();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
        logger.info(sdf.format(new Date()) + "----(" + randome + ")请求参数:" + json);
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(this.getRequestConfig());
        httpPost.setEntity(new StringEntity(json, ContentType.create(ContentType.APPLICATION_JSON.getMimeType(), Charset.forName("UTF-8"))));
        CloseableHttpResponse httpResponse = getHttpCline().execute(httpPost);
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        logger.info(sdf.format(new Date()) + "----(" + randome + ")返回结果:" + content);
        HttpResult httpResult = HttpResult.getHttpResult(statusCode, content);
        this.close(httpResponse);
        return httpResult;
    }
    /**
     * 发送XML请求
     * @param url       请求地址
     * @param xml       XML数据
     * @param header    自定义请求头
     * @return
     */
    public HttpResult pushHttpRequsetXml(String url, String xml, Map<String, String> header) throws Exception{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(getRequestConfig());
        for(String key : header.keySet()){
            httpPost.setHeader(key, header.get(key));
        }
        httpPost.setHeader("Content-Type", "application/xml");
        httpPost.setEntity(new StringEntity(xml, "UTF-8"));
        CloseableHttpResponse httpResponse = getHttpCline().execute(httpPost);
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        HttpResult httpResult = HttpResult.getHttpResult(statusCode, content);
        this.close(httpResponse);
        return httpResult;
    }
    /**
     * 请求https发送XML请求
     * @param url           接口路径
     * @param xml           内容
     * @param header        请求头
     * @param certPassword      证书密码
     * @param certPath      证书路径
     * @param certType      证书类型
     * @return
     * @throws Exception
     */
    public String pushHttpsRequsetXml(String url, String xml, Map<String, String> header, String certPassword, String certPath, String certType) throws Exception{
        HttpPost httpPost = new HttpPost(url);
        for(String key : header.keySet()){
            httpPost.setHeader(key, header.get(key));
        }
        httpPost.setHeader("Content-Type", "application/xml");
        httpPost.setEntity(new StringEntity(xml, "UTF-8"));
        CloseableHttpClient httpCline = this.initCert(certPassword, certPath, certType);
        CloseableHttpResponse httpResponse = httpCline.execute(httpPost);
        String content = null;
        if(httpResponse.getStatusLine().getStatusCode() == 200){
            content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        }else{
            content = "返回状态码:" + httpResponse.getStatusLine() + "。" + EntityUtils.toString(httpResponse.getEntity());
        }
        this.close(httpResponse);
        httpCline.close();
        return content;
    }
    /**
     * 初始化https对象(带证书)
     * @param key       证书密码
     * @param certPath  证书路径
     * @param certType  证书类型
     * @throws Exception
     */
    private CloseableHttpClient initCert(String key, String certPath, String certType) throws Exception {
        KeyStore keyStore = KeyStore.getInstance(certType);
        InputStream inputStream = new FileInputStream(new File(certPath));
        try {
            keyStore.load(inputStream, key.toCharArray());
        } finally {
            inputStream.close();
        }
        SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, key.toCharArray()).build();
        SSLConnectionSocketFactory sslsf =
                new SSLConnectionSocketFactory(sslcontext, new String[] {"TLSv1"}, null,
                        SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
        return HttpClients.custom().setSSLSocketFactory(sslsf).build();
    }
    /**
     * 关闭资源
     */
    private void close(CloseableHttpResponse httpResponse){
        try {
            if(null != httpResponse){
                EntityUtils.consume(httpResponse.getEntity());//此处高能,通过源码分析,由EntityUtils是否回收HttpEntity
                httpResponse.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if(null != httpResponse){
                    httpResponse.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/httpClinet/HttpResult.java
New file
@@ -0,0 +1,31 @@
package com.stylefeng.guns.modular.system.util.httpClinet;
import lombok.Data;
/**
 * http请求返回封装
 */
@Data
public class HttpResult {
    /**
     * 返回状态码
     */
    private Integer code;
    /**
     * 返回结果
     */
    private String data;
    /**
     * 返回封装结果
     * @param code
     * @param data
     * @return
     */
    public static HttpResult getHttpResult(Integer code, String data){
        HttpResult httpResult = new HttpResult();
        httpResult.setCode(code);
        httpResult.setData(data);
        return httpResult;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/AES.java
New file
@@ -0,0 +1,72 @@
package com.stylefeng.guns.modular.system.util.weChat;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.*;
/**
* AES加密
* @author pzb
* @Date 2021/12/3 15:43
*/
public class AES {
    public static boolean initialized = false;
    /**
     * AES解密
     *
     * @param content
     *            密文
     * @return
     * @throws InvalidAlgorithmParameterException
     * @throws NoSuchProviderException
     */
    public byte[] decrypt(byte[] content, byte[] keyByte, byte[] ivByte) throws InvalidAlgorithmParameterException {
        initialize();
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
            Key sKeySpec = new SecretKeySpec(keyByte, "AES");
            cipher.init(Cipher.DECRYPT_MODE, sKeySpec, generateIV(ivByte));// 初始化
            byte[] result = cipher.doFinal(content);
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static void initialize() {
        if (initialized)
            return;
        Security.addProvider(new BouncyCastleProvider());
        initialized = true;
    }
    // 生成iv
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
        AlgorithmParameters params = AlgorithmParameters.getInstance("AES");
        params.init(new IvParameterSpec(iv));
        return params;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/AesException.java
New file
@@ -0,0 +1,59 @@
package com.stylefeng.guns.modular.system.util.weChat;
@SuppressWarnings("serial")
public class AesException extends Exception {
    public final static int OK = 0;
    public final static int ValidateSignatureError = -40001;
    public final static int ParseXmlError = -40002;
    public final static int ComputeSignatureError = -40003;
    public final static int IllegalAesKey = -40004;
    public final static int ValidateAppidError = -40005;
    public final static int EncryptAESError = -40006;
    public final static int DecryptAESError = -40007;
    public final static int IllegalBuffer = -40008;
    //public final static int EncodeBase64Error = -40009;
    //public final static int DecodeBase64Error = -40010;
    //public final static int GenReturnXmlError = -40011;
    private int code;
    private static String getMessage(int code) {
        switch (code) {
        case ValidateSignatureError:
            return "签名验证错误";
        case ParseXmlError:
            return "xml解析失败";
        case ComputeSignatureError:
            return "sha加密生成签名失败";
        case IllegalAesKey:
            return "SymmetricKey非法";
        case ValidateAppidError:
            return "appid校验失败";
        case EncryptAESError:
            return "aes加密失败";
        case DecryptAESError:
            return "aes解密失败";
        case IllegalBuffer:
            return "解密后得到的buffer非法";
//        case EncodeBase64Error:
//            return "base64加密错误";
//        case DecodeBase64Error:
//            return "base64解密错误";
//        case GenReturnXmlError:
//            return "xml生成失败";
        default:
            return null; // cannot be
        }
    }
    public int getCode() {
        return code;
    }
    AesException(int code) {
        super(getMessage(code));
        this.code = code;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/ByteGroup.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.util.weChat;
import java.util.ArrayList;
class ByteGroup {
    ArrayList<Byte> byteContainer = new ArrayList<Byte>();
    public byte[] toBytes() {
        byte[] bytes = new byte[byteContainer.size()];
        for (int i = 0; i < byteContainer.size(); i++) {
            bytes[i] = byteContainer.get(i);
        }
        return bytes;
    }
    public ByteGroup addBytes(byte[] bytes) {
        for (byte b : bytes) {
            byteContainer.add(b);
        }
        return this;
    }
    public int size() {
        return byteContainer.size();
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/PKCS7Encoder.java
New file
@@ -0,0 +1,67 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.stylefeng.guns.modular.system.util.weChat;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
 * 提供基于PKCS7算法的加解密接口.
 */
class PKCS7Encoder {
    static Charset CHARSET = Charset.forName("utf-8");
    static int BLOCK_SIZE = 32;
    /**
     * 获得对明文进行补位填充的字节.
     *
     * @param count 需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }
    /**
     * 删除解密后明文的补位字符
     *
     * @param decrypted 解密后的明文
     * @return 删除补位字符后的明文
     */
    static byte[] decode(byte[] decrypted) {
        int pad = (int) decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }
    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     *
     * @param a 需要转化的数字
     * @return 转化得到的字符
     */
    static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/SHA1.java
New file
@@ -0,0 +1,61 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.stylefeng.guns.modular.system.util.weChat;
import java.security.MessageDigest;
import java.util.Arrays;
/**
 * SHA1 class
 *
 * 计算公众平台的消息签名接口.
 */
public class SHA1 {
    /**
     * 用SHA1算法生成安全签名
     * @param token 票据
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @param encrypt 密文
     * @return 安全签名
     * @throws AesException
     */
    public static String getSHA1(String token, String timestamp, String nonce, String encrypt) throws AesException
              {
        try {
            String[] array = new String[] { token, timestamp, nonce, encrypt };
            StringBuffer sb = new StringBuffer();
            // 字符串排序
            Arrays.sort(array);
            for (int i = 0; i < 4; i++) {
                sb.append(array[i]);
            }
            String str = sb.toString();
            // SHA1签名生成
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            md.update(str.getBytes());
            byte[] digest = md.digest();
            StringBuffer hexstr = new StringBuffer();
            String shaHex = "";
            for (int i = 0; i < digest.length; i++) {
                shaHex = Integer.toHexString(digest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexstr.append(0);
                }
                hexstr.append(shaHex);
            }
            return hexstr.toString();
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ComputeSignatureError);
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/SubscribeMessageUtil.java
New file
@@ -0,0 +1,264 @@
package com.stylefeng.guns.modular.system.util.weChat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.modular.system.util.RedisUtil;
import com.stylefeng.guns.modular.system.util.ResultUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult;
import com.stylefeng.guns.modular.system.util.weChat.model.Category;
import com.stylefeng.guns.modular.system.util.weChat.model.MessageTemplate;
import com.stylefeng.guns.modular.system.util.weChat.model.PubTemplateKeywords;
import com.stylefeng.guns.modular.system.util.weChat.model.PubTemplatetitles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * 订阅消息
 */
@Component
public class SubscribeMessageUtil {
    @Value("${wx.appletsAppid}")
    private String wxAppletsAppid;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 获取消息类目
     * @return
     */
    public ResultUtil<List<Category>> getcategory(){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getcategory?access_token=" + accessToken;
            HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息类目失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            JSONArray data = jsonObject.getJSONArray("data");
            List<Category> categories = data.toJavaList(Category.class);
            return ResultUtil.success(categories);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 获取所属类目下的公共模板
     * @param ids
     * @return
     */
    public ResultUtil<List<PubTemplatetitles>> getpubtemplatetitles(String ids){
        List<PubTemplatetitles> pubTemplatetitles = new ArrayList<>();
        try {
            Integer start = 0;
            while (true){
                String accessToken = redisUtil.getValue("wxAppletsAccessToken");
                String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatetitles?access_token=" + accessToken;
                Map<String, Object> params = new HashMap<>();
                params.put("ids", ids);
                params.put("start", start + "");
                params.put("limit", 30);
                HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, params, null, "form");
                if(httpResult.getCode() != 200){
                    return ResultUtil.error("获取消息类目失败");
                }
                JSONObject jsonObject = JSON.parseObject(httpResult.getData());
                Integer errcode = jsonObject.getInteger("errcode");
                if(0 != errcode){
                    return ResultUtil.error(jsonObject.getString("errmsg"));
                }
                JSONArray data = jsonObject.getJSONArray("data");
                List<PubTemplatetitles> pubTemplatetitles1 = data.toJavaList(PubTemplatetitles.class);
                if(pubTemplatetitles1.size() == 0){
                    break;
                }
                pubTemplatetitles.addAll(pubTemplatetitles1);
                start += 30;
            }
            return ResultUtil.success(pubTemplatetitles);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 获取关键词列表
     * @param tid
     * @return
     */
    public ResultUtil<List<PubTemplateKeywords>> getpubtemplatekeywords(String tid){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxaapi/newtmpl/getpubtemplatekeywords?access_token=" + accessToken;
            Map<String, Object> params = new HashMap<>();
            params.put("tid", tid);
            HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, params, null, "form");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息类目失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            JSONArray data = jsonObject.getJSONArray("data");
            List<PubTemplateKeywords> pubTemplateKeywords = data.toJavaList(PubTemplateKeywords.class);
            return ResultUtil.success(pubTemplateKeywords);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 获取个人模板列表
     * @return
     */
    public ResultUtil<List<MessageTemplate>> getMessageTemplateList(){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxaapi/newtmpl/gettemplate?access_token=" + accessToken;
            HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息模板失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            JSONArray data = jsonObject.getJSONArray("data");
            List<MessageTemplate> messageTemplates = data.toJavaList(MessageTemplate.class);
            return ResultUtil.success(messageTemplates);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 添加消息模板
     * @param tid           模板标题 id
     * @param kidList       开发者自行组合好的模板关键词列表,关键词顺序可以自由搭配(例如 [3,5,4] 或 [4,5,3]),最多支持5个,最少2个关键词组合
     * @param sceneDesc     服务场景描述,15个字以内
     * @return
     */
    public ResultUtil<String> addtemplate(String tid, String[] kidList, String sceneDesc){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxaapi/newtmpl/addtemplate?access_token=" + accessToken;
            Map<String, Object> params = new HashMap<>();
            params.put("tid", tid);
            params.put("kidList", kidList);
            params.put("sceneDesc", sceneDesc);
            HttpResult httpResult = httpClientUtil.pushHttpRequset("POST", url, params, null, "json");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息模板失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            String priTmplId = jsonObject.getString("priTmplId");
            return ResultUtil.success(priTmplId);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 删除模板
     * @param priTmplId     模板id
     * @return
     */
    public ResultUtil deltemplate(String priTmplId){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxaapi/newtmpl/deltemplate?access_token=" + accessToken;
            Map<String, Object> params = new HashMap<>();
            params.put("priTmplId", priTmplId);
            HttpResult httpResult = httpClientUtil.pushHttpRequset("POST", url, params, null, "json");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息模板失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            return ResultUtil.success();
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
    /**
     * 发送消息
     * @param template_id           所需下发的订阅模板id
     * @param page                  点击模板卡片后的跳转页面,仅限本小程序内的页面。支持带参数,(示例index?foo=bar)。该字段不填则模板无跳转
     * @param touser                接收者(用户)的 openid
     * @param data                  模板内容,格式形如 { "key1": { "value": any }, "key2": { "value": any } }的object
     * @param miniprogram_state     跳转小程序类型:developer为开发版;trial为体验版;formal为正式版;默认为正式版
     * @param lang                  进入小程序查看”的语言类型,支持zh_CN(简体中文)、en_US(英文)、zh_HK(繁体中文)、zh_TW(繁体中文),默认为zh_CN
     * @return
     */
    public ResultUtil send(String template_id, String page, String touser, String data, String miniprogram_state, String lang){
        try {
            String accessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
            Map<String, Object> params = new HashMap<>();
            params.put("template_id", template_id);
            params.put("page", page);
            params.put("touser", touser);
            params.put("data", JSON.parseObject(data));
            params.put("miniprogram_state", miniprogram_state);
            params.put("lang", lang);
            HttpResult httpResult = httpClientUtil.pushHttpRequset("POST", url, params, null, "json");
            if(httpResult.getCode() != 200){
                return ResultUtil.error("获取消息模板失败");
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            Integer errcode = jsonObject.getInteger("errcode");
            if(0 != errcode){
                return ResultUtil.error(jsonObject.getString("errmsg"));
            }
            return ResultUtil.success();
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.runErr();
        }
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WXBizMsgCrypt.java
New file
@@ -0,0 +1,289 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
/**
 * 针对org.apache.commons.codec.binary.Base64,
 * 需要导入架包commons-codec-1.9(或commons-codec-1.8等其他版本)
 * 官方下载地址:http://commons.apache.org/proper/commons-codec/download_codec.cgi
 */
package com.stylefeng.guns.modular.system.util.weChat;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/**
 * 提供接收和推送给公众平台消息的加解密接口(UTF8编码的字符串).
 * <ol>
 *     <li>第三方回复加密消息给公众平台</li>
 *     <li>第三方收到公众平台发送的消息,验证消息的安全性,并对消息进行解密。</li>
 * </ol>
 * 说明:异常java.security.InvalidKeyException:illegal Key Size的解决方案
 * <ol>
 *     <li>在官方网站下载JCE无限制权限策略文件(JDK7的下载地址:
 *      http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html</li>
 *     <li>下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt</li>
 *     <li>如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件</li>
 *     <li>如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件</li>
 * </ol>
 */
public class WXBizMsgCrypt {
    static Charset CHARSET = Charset.forName("utf-8");
    Base64 base64 = new Base64();
    byte[] aesKey;
    String token;
    String appId;
    /**
     * 构造函数
     * @param token 公众平台上,开发者设置的token
     * @param encodingAesKey 公众平台上,开发者设置的EncodingAESKey
     * @param appId 公众平台appid
     *
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public WXBizMsgCrypt(String token, String encodingAesKey, String appId) throws AesException {
        if (encodingAesKey.length() != 43) {
            throw new AesException(AesException.IllegalAesKey);
        }
        this.token = token;
        this.appId = appId;
        aesKey = Base64.decodeBase64(encodingAesKey + "=");
    }
    // 生成4个字节的网络字节序
    byte[] getNetworkBytesOrder(int sourceNumber) {
        byte[] orderBytes = new byte[4];
        orderBytes[3] = (byte) (sourceNumber & 0xFF);
        orderBytes[2] = (byte) (sourceNumber >> 8 & 0xFF);
        orderBytes[1] = (byte) (sourceNumber >> 16 & 0xFF);
        orderBytes[0] = (byte) (sourceNumber >> 24 & 0xFF);
        return orderBytes;
    }
    // 还原4个字节的网络字节序
    int recoverNetworkBytesOrder(byte[] orderBytes) {
        int sourceNumber = 0;
        for (int i = 0; i < 4; i++) {
            sourceNumber <<= 8;
            sourceNumber |= orderBytes[i] & 0xff;
        }
        return sourceNumber;
    }
    // 随机生成16位字符串
    String getRandomStr() {
        String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 16; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }
    /**
     * 对明文进行加密.
     *
     * @param text 需要加密的明文
     * @return 加密后base64编码的字符串
     * @throws AesException aes加密失败
     */
    String encrypt(String randomStr, String text) throws AesException {
        ByteGroup byteCollector = new ByteGroup();
        byte[] randomStrBytes = randomStr.getBytes(CHARSET);
        byte[] textBytes = text.getBytes(CHARSET);
        byte[] networkBytesOrder = getNetworkBytesOrder(textBytes.length);
        byte[] appidBytes = appId.getBytes(CHARSET);
        // randomStr + networkBytesOrder + text + appid
        byteCollector.addBytes(randomStrBytes);
        byteCollector.addBytes(networkBytesOrder);
        byteCollector.addBytes(textBytes);
        byteCollector.addBytes(appidBytes);
        // ... + pad: 使用自定义的填充方式对明文进行补位填充
        byte[] padBytes = PKCS7Encoder.encode(byteCollector.size());
        byteCollector.addBytes(padBytes);
        // 获得最终的字节流, 未加密
        byte[] unencrypted = byteCollector.toBytes();
        try {
            // 设置加密模式为AES的CBC模式
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            // 加密
            byte[] encrypted = cipher.doFinal(unencrypted);
            // 使用BASE64对加密后的字符串进行编码
            String base64Encrypted = base64.encodeToString(encrypted);
            return base64Encrypted;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.EncryptAESError);
        }
    }
    /**
     * 对密文进行解密.
     *
     * @param text 需要解密的密文
     * @return 解密得到的明文
     * @throws AesException aes解密失败
     */
    String decrypt(String text) throws AesException {
        byte[] original;
        try {
            // 设置解密模式为AES的CBC模式
            Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
            SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
            IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
            cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
            // 使用BASE64对密文进行解码
            byte[] encrypted = Base64.decodeBase64(text);
            // 解密
            original = cipher.doFinal(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.DecryptAESError);
        }
        String xmlContent, from_appid;
        try {
            // 去除补位字符
            byte[] bytes = PKCS7Encoder.decode(original);
            // 分离16位随机字符串,网络字节序和AppId
            byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
            int xmlLength = recoverNetworkBytesOrder(networkOrder);
            xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
            from_appid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length),
                    CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.IllegalBuffer);
        }
        // appid不相同的情况
        if (!from_appid.equals(appId)) {
            throw new AesException(AesException.ValidateAppidError);
        }
        return xmlContent;
    }
    /**
     * 将公众平台回复用户的消息加密打包.
     * <ol>
     *     <li>对要发送的消息进行AES-CBC加密</li>
     *     <li>生成安全签名</li>
     *     <li>将消息密文和安全签名打包成xml格式</li>
     * </ol>
     *
     * @param replyMsg 公众平台待回复用户的消息,xml格式的字符串
     * @param timeStamp 时间戳,可以自己生成,也可以用URL参数的timestamp
     * @param nonce 随机串,可以自己生成,也可以用URL参数的nonce
     *
     * @return 加密后的可以直接回复用户的密文,包括msg_signature, timestamp, nonce, encrypt的xml格式的字符串
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String encryptMsg(String replyMsg, String timeStamp, String nonce) throws AesException {
        // 加密
        String encrypt = encrypt(getRandomStr(), replyMsg);
        // 生成安全签名
        if (timeStamp == "") {
            timeStamp = Long.toString(System.currentTimeMillis());
        }
        String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt);
        // System.out.println("发送给平台的签名是: " + signature[1].toString());
        // 生成发送的xml
        String result = XMLParse.generate(encrypt, signature, timeStamp, nonce);
        return result;
    }
    /**
     * 检验消息的真实性,并且获取解密后的明文.
     * <ol>
     *     <li>利用收到的密文生成安全签名,进行签名验证</li>
     *     <li>若验证通过,则提取xml中的加密消息</li>
     *     <li>对消息进行解密</li>
     * </ol>
     *
     * @param msgSignature 签名串,对应URL参数的msg_signature
     * @param timeStamp 时间戳,对应URL参数的timestamp
     * @param nonce 随机串,对应URL参数的nonce
     * @param postData 密文,对应POST请求的数据
     *
     * @return 解密后的原文
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String decryptMsg(String msgSignature, String timeStamp, String nonce, String postData)
            throws AesException {
        // 密钥,公众账号的app secret
        // 提取密文
        Object[] encrypt = XMLParse.extract(postData);
        // 验证安全签名
        String signature = SHA1.getSHA1(token, timeStamp, nonce, encrypt[1].toString());
        // 和URL中的签名比较是否相等
        // System.out.println("第三方收到URL中的签名:" + msg_sign);
        // System.out.println("第三方校验签名:" + signature);
        if (!signature.equals(msgSignature)) {
            throw new AesException(AesException.ValidateSignatureError);
        }
        // 解密
        String result = decrypt(encrypt[1].toString());
        return result;
    }
    /**
     * 验证URL
     * @param msgSignature 签名串,对应URL参数的msg_signature
     * @param timeStamp 时间戳,对应URL参数的timestamp
     * @param nonce 随机串,对应URL参数的nonce
     * @param echoStr 随机串,对应URL参数的echostr
     *
     * @return 解密之后的echostr
     * @throws AesException 执行失败,请查看该异常的错误码和具体的错误信息
     */
    public String verifyUrl(String msgSignature, String timeStamp, String nonce, String echoStr)
            throws AesException {
        String signature = SHA1.getSHA1(token, timeStamp, nonce, "");
        if (!signature.equals(msgSignature)) {
            throw new AesException(AesException.ValidateSignatureError);
        }
        String result = decrypt(echoStr);
        return result;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WXCore.java
New file
@@ -0,0 +1,54 @@
package com.stylefeng.guns.modular.system.util.weChat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
public class WXCore {
    private static Logger logger = LoggerFactory.getLogger(WXCore.class);
    private static final String WATERMARK = "watermark";
    @Value("${wx.appletsAppid}")
    private static String appid ;
    /**
     * 解密数据
     * @return
     * @throws Exception
     */
    public static String decrypt(String encryptedData, String sessionKey, String iv){
        String result = "";
        try {
            AES aes = new AES();
            byte[] resultByte = aes.decrypt(Base64.decodeBase64(encryptedData), Base64.decodeBase64(sessionKey), Base64.decodeBase64(iv));
            if(null != resultByte && resultByte.length > 0){
                result = new String(WxPKCS7Encoder.decode(resultByte), "UTF-8");
//                JSONObject jsonObject = JSON.parseObject(result);
//                String decryptAppid = jsonObject.getJSONObject(WATERMARK).getString("appid");
//                if(!appid.equals(decryptAppid)){
//                    result = "";
//                }
            }
        } catch (Exception e) {
            result = "";
            e.printStackTrace();
        }
        return result;
    }
    public static void main(String[] args) throws Exception{
        String appId = "wx4f4bc4dec97d474b";
        String encryptedData = "ajhisfk0EhWCBcoxt/5QJA3bKPTygQXANbCSev92MyqIqGxRhzZFS1SlQrIWAo3tx8YfsB+VlScZNOlRyfnXKqPUl9h+PDeKsTkTst9V4pq4mUbI+r3AautXBffVk/rpyjMfanVsWeOlxkupdv2U9U4BrueR/Rak+TCmHTWUUf8eDLoi6nioL/Pft/rYaO3JD54hgpcY0Ef/k7Boyap4E0/uKVowY1ANO7KVydSXE6S7OKzXuzmDTbV38v+7ryMHtglUzoKzF1gL8y9OZRwkaesfHN1kfItjpsAibjSgkIiiW6ZEHLT2n1UDkJtfUqg63je2cJAH7gzeUm9TCDDftdhLU+NuPk3j/LXyFQ05pJ8B19+kIXF3dcmHOH7lFvi7yGmVuAD/9AnetGWgId3TZDS/OjbiVUM30RogeziAw98VpAyAAq1r2ULFwi8e928m";
        String sessionKey = "CdxFGwXIluQFZ+qD+NSFKQ==";
        String iv = "3FD8r1Spwlf7LG8YEq41+Q==";
        logger.debug(decrypt(encryptedData, sessionKey, iv));
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WeChatUtil.java
New file
@@ -0,0 +1,435 @@
package com.stylefeng.guns.modular.system.util.weChat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.stylefeng.guns.core.util.ToolUtil;
import com.stylefeng.guns.modular.system.util.RedisUtil;
import com.stylefeng.guns.modular.system.util.UUIDUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpClientUtil;
import com.stylefeng.guns.modular.system.util.httpClinet.HttpResult;
import org.apache.commons.codec.digest.DigestUtils;
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.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import java.io.*;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
/**
 * 微信工具类
 */
@Component
public class WeChatUtil {
    private static Logger logger = LoggerFactory.getLogger(WeChatUtil.class);
    @Value("${wx.appletsAppid}")
    private String wxAppletsAppid;
    @Value("${wx.appletsAppSecret}")
    private String wxAppletsAppSecret;
    @Value("${wx.officialAccountAppid}")
    private String officialAccountAppid;
    @Value("{wx.officialAccountAppSecret}")
    private String officialAccountAppSecret;
    @Value("${wx.appid}")
    private String webAppId;
    @Value("${wx.appSecret}")
    private String webAppSecret;
    @Autowired
    private HttpClientUtil httpClientUtil;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RedisUtil redisUtil;
    {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(30000);
                    new Timer().schedule(new TimerTask() {
                        @Override
                        public void run() {
                            try {
                                String wxAppletsAccessToken = getWxAppletsAccessToken();
                                if(ToolUtil.isEmpty(wxAppletsAccessToken)){
                                    System.err.println("获取微信小程序access_token失败");
                                }
                                redisUtil.setStrValue("wxAppletsAccessToken", wxAppletsAccessToken, 7000);
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }, 0, 7000000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }
    /**
     * 小程序使用jscode获取openid
     * @param jscode
     * @return
     */
    public Map<String, Object> code2Session(String jscode) throws Exception{
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret
                + "&js_code=" + jscode + "&grant_type=authorization_code";
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(null == httpResult || httpResult.getCode() != 200){
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        int errcode = jsonObject.getIntValue("errcode");
        Map<String, Object> map = new HashMap<>();
        map.put("errcode", errcode);
        if(errcode == 0){//成功
            map.put("openid", jsonObject.getString("openid"));
            map.put("sessionKey", jsonObject.getString("session_key"));
            map.put("unionid", jsonObject.getString("unionid"));
            return map;
        }
        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 40029){//code 无效
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 45011){//频率限制,每个用户每分钟100次
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 40226){//高风险等级用户,小程序登录拦截 。
            map.put("msg", jsonObject.getString("errmsg"));
        }
        map.put("msg", jsonObject.getString("errmsg"));
        return map;
    }
    /**
     * 获取微信小程序token
     * @return
     */
    public String getWxAppletsAccessToken() throws Exception{
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + wxAppletsAppid + "&secret=" + wxAppletsAppSecret;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(httpResult.getCode() != 200){
            return "";
        }
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        return jsonObject.getString("access_token");
    }
    /***
     * 获取jsapiTicket(小程序)
     * 来源 www.vxzsk.com
     * @return
     */
    public String getWxAppletsJSApiTicket() throws Exception{
        String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + wxAppletsAccessToken + "&type=jsapi";
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", urlStr, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        logger.debug(httpResult.getData());
        String ticket = JSONObject.parseObject(httpResult.getData()).getString("ticket");
        return  ticket;
    }
    /**
     * 通过config接口注入权限验证配置(小程序)
     * 附录1-JS-SDK使用权限签名算法,
     * @return
     */
    public Map<String,Object> getWxAppletsSignatureConfig(String url) throws Exception{
        //获取token
        try {
            url = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String ticket = getWxAppletsJSApiTicket();
        String noncestr = UUIDUtil.getRandomCode();
        Long timestamp = System.currentTimeMillis();
        String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        String signature = DigestUtils.sha1Hex(content);
        Map<String,Object> map=new HashMap<>();
        map.put("appId", wxAppletsAppid);
        map.put("timestamp", timestamp);
        map.put("nonceStr", noncestr);
        map.put("signature", signature);
        return  map;
    }
    /**
     * 网站应用登录
     * @param code
     * @return
     */
    public Map<String, String> webAccessToken(String code) throws Exception{
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + webAppId + "&secret=" + webAppSecret + "&code=" + code + "&grant_type=authorization_code";
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        int errcode = jsonObject.getIntValue("errcode");
        Map<String, String> map = new HashMap<>();
        if(errcode == 0){//成功
            map.put("access_token", jsonObject.getString("access_token"));
            map.put("openid", jsonObject.getString("openid"));
            map.put("refresh_token", jsonObject.getString("refresh_token"));
            map.put("unionid", jsonObject.getString("unionid"));
            return map;
        }
        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 40029){//code 无效
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 45011){//频率限制,每个用户每分钟100次
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        return map;
    }
    /**
     * 获取微信个人信息
     * @param access_token
     * @param openid
     * @return
     */
    public Map<String, Object> getUserInfo(String access_token, String openid) throws Exception{
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        JSONObject jsonObject = JSON.parseObject(httpResult.getData());
        int errcode = jsonObject.getIntValue("errcode");
        Map<String, Object> map = new HashMap<>();
        if(errcode == 0){//成功
            map.put("nickname", jsonObject.getString("nickname"));
            map.put("openid", jsonObject.getString("openid"));
            map.put("sex", jsonObject.getString("sex"));
            map.put("headimgurl", jsonObject.getString("headimgurl"));
            return map;
        }
        if(errcode == -1){//系统繁忙,此时请开发者稍候再试
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 40029){//code 无效
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        if(errcode == 45011){//频率限制,每个用户每分钟100次
            map.put("msg", jsonObject.getString("errmsg"));
            return map;
        }
        return map;
    }
    /**
     * 公众号获取openid
     * @param code
     * @return
     */
    public Map<String,Object> getOpenId(String code) throws Exception{
        if (code == null || code.length() == 0) {
            return null;
        }
        String grantType = "authorization_code";
        String params = "appid=" + officialAccountAppid + "&secret=" + officialAccountAppSecret + "&code=" + code + "&grant_type=" + grantType;
        logger.debug("sssss"+params);
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", "https://api.weixin.qq.com/sns/oauth2/access_token?" + params, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        JSONObject json = JSON.parseObject(httpResult.getData());
        logger.debug(json.toJSONString());
        String openId = json.get("openid").toString();
        String accessToken = json.get("access_token").toString();
        Integer expiresIn = json.getInteger("expires_in");
        String refresh_token = json.getString("refresh_token");
        String unionid = json.getString("unionid");
        Map<String,Object> map=new HashMap<>();
        map.put("openId",openId);
        map.put("accessToken",accessToken);
        map.put("expiresIn", expiresIn);
        map.put("refreshToken", refresh_token);
        map.put("unionid", unionid);
        return map;
    }
    /***
     * 获取acess_token (公众号)
     * 来源www.vxzsk.com
     * @return
     */
    public String getAccessToken() throws Exception{
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + officialAccountAppid
                + "&secret=" + officialAccountAppSecret;
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        String accessToken = JSONObject.parseObject(httpResult.getData()).getString("access_token");
        return accessToken;
    }
    /***
     * 获取jsapiTicket(公众号)
     * 来源 www.vxzsk.com
     * @return
     */
    public String getJSApiTicket() throws Exception{
        //获取token
        String acess_token = redisUtil.getValue("acess_token");
        String urlStr = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + acess_token + "&type=jsapi";
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", urlStr, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        logger.debug(httpResult.getData());
        String ticket = JSONObject.parseObject(httpResult.getData()).getString("ticket");
        return  ticket;
    }
    /**
     * 通过config接口注入权限验证配置(公众号)
     * 附录1-JS-SDK使用权限签名算法,
     * @return
     */
    public Map<String,Object> getSignatureConfig(String url) throws Exception{
        //获取token
        try {
            url = URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String ticket = getJSApiTicket();
        String noncestr = UUIDUtil.getRandomCode();
        Long timestamp = System.currentTimeMillis();
        String content = "jsapi_ticket=" + ticket + "&noncestr=" + noncestr + "&timestamp=" + timestamp + "&url=" + url;
        String signature = DigestUtils.sha1Hex(content);
        Map<String,Object> map=new HashMap<>();
        map.put("appId", officialAccountAppid);
        map.put("timestamp", timestamp);
        map.put("nonceStr", noncestr);
        map.put("signature", signature);
        return  map;
    }
    /**
     * 公众号获取用户个人信息
     * @param access_token
     * @param openid
     * @return
     */
    public Map<String, Object> queryUserInfo(String access_token, String openid) throws Exception{
        String url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN";
        HttpResult httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        if(httpResult.getCode() != 200){
            return null;
        }
        logger.debug(httpResult.getData());
        JSONObject j = JSON.parseObject(httpResult.getData());
        Map<String, Object> map = new HashMap<>();
        map.put("nickname", j.getString("nickname"));
        map.put("sex", j.getInteger("sex"));
        map.put("headimgurl", j.getString("headimgurl"));
        map.put("unionid", j.getString("unionid"));
        return map;
    }
    /**
     * 获取小程序二维码
     * @param page      跳转页 例如 pages/index/index
     * @param scene     参数 a=1&b=2
     */
    public InputStream getwxacodeunlimit(String page, String scene, String envVersion) throws Exception{
        try {
            String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
            String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=" + wxAppletsAccessToken;
            Map<String, Object> param = new HashMap<>();
            param.put("scene", scene);
            param.put("page", page);
            param.put("env_version", envVersion);
            HttpHeaders httpHeaders = new HttpHeaders();
            MediaType type=MediaType.parseMediaType("application/json;charset=UTF-8");
            httpHeaders.setContentType(type);
            HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders);
            ResponseEntity<byte[]> entity  = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] body = entity.getBody();
            return new ByteArrayInputStream(body);
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 获取小程序urlscheme码
     * @return
     */
    public String getUrlscheme(String path) throws Exception{
        String wxAppletsAccessToken = redisUtil.getValue("wxAppletsAccessToken");
        String url = "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + wxAppletsAccessToken;
        Map<String, Object> param = new HashMap<>();
        param.put("is_expire", true);
        param.put("expire_type", 1);
        param.put("expire_interval", 180);
        Map<String, Object> map1 = new HashMap<>();
        map1.put("path", path);
        map1.put("query", "");
        map1.put("env_version", "release");
        param.put("jump_wxa", map1);
        HttpHeaders httpHeaders = new HttpHeaders();
        MediaType type=MediaType.parseMediaType("application/json;charset=UTF-8");
        httpHeaders.setContentType(type);
        HttpEntity<Map<String, Object>> requestEntity = new HttpEntity<>(param, httpHeaders);
        ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class);
        String body1 = exchange.getBody();
        return body1;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/WxPKCS7Encoder.java
New file
@@ -0,0 +1,63 @@
package com.stylefeng.guns.modular.system.util.weChat;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* 微信小程序加解密
* @author pzb
* @Date 2021/12/3 15:43
*/
public class WxPKCS7Encoder {
    private static final Charset CHARSET = Charset.forName("utf-8");
    private static final int BLOCK_SIZE = 32;
    /**
     * 获得对明文进行补位填充的字节.
     *
     * @param count
     *            需要进行填充补位操作的明文字节个数
     * @return 补齐用的字节数组
     */
    public static byte[] encode(int count) {
        // 计算需要填充的位数
        int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
        if (amountToPad == 0) {
            amountToPad = BLOCK_SIZE;
        }
        // 获得补位所用的字符
        char padChr = chr(amountToPad);
        String tmp = new String();
        for (int index = 0; index < amountToPad; index++) {
            tmp += padChr;
        }
        return tmp.getBytes(CHARSET);
    }
    /**
     * 删除解密后明文的补位字符
     *
     * @param decrypted
     *            解密后的明文
     * @return 删除补位字符后的明文
     */
    public static byte[] decode(byte[] decrypted) {
        int pad = decrypted[decrypted.length - 1];
        if (pad < 1 || pad > 32) {
            pad = 0;
        }
        return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
    }
    /**
     * 将数字转化成ASCII码对应的字符,用于对明文进行补码
     *
     * @param a
     *            需要转化的数字
     * @return 转化得到的字符
     */
    public static char chr(int a) {
        byte target = (byte) (a & 0xFF);
        return (char) target;
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/XMLParse.java
New file
@@ -0,0 +1,72 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.stylefeng.guns.modular.system.util.weChat;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
/**
 * XMLParse class
 *
 * 提供提取消息格式中的密文及生成回复消息格式的接口.
 */
class XMLParse {
    /**
     * 提取出xml数据包中的加密消息
     * @param xmltext 待提取的xml字符串
     * @return 提取出的加密消息字符串
     * @throws AesException
     */
    public static Object[] extract(String xmltext) throws AesException     {
        Object[] result = new Object[3];
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(xmltext);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Encrypt");
            NodeList nodelist2 = root.getElementsByTagName("ToUserName");
            result[0] = 0;
            result[1] = nodelist1.item(0).getTextContent();
            result[2] = nodelist2.item(0).getTextContent();
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new AesException(AesException.ParseXmlError);
        }
    }
    /**
     * 生成xml消息
     * @param encrypt 加密后的消息密文
     * @param signature 安全签名
     * @param timestamp 时间戳
     * @param nonce 随机字符串
     * @return 生成的xml字符串
     */
    public static String generate(String encrypt, String signature, String timestamp, String nonce) {
        String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
                + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
                + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "</xml>";
        return String.format(format, encrypt, signature, timestamp, nonce);
    }
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/Category.java
New file
@@ -0,0 +1,18 @@
package com.stylefeng.guns.modular.system.util.weChat.model;
import lombok.Data;
/**
 * 订阅消息类目
 */
@Data
public class Category {
    /**
     * 类目id
     */
    private String id;
    /**
     * 类目名称
     */
    private String name;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/KeywordEnum.java
New file
@@ -0,0 +1,17 @@
package com.stylefeng.guns.modular.system.util.weChat.model;
import lombok.Data;
import java.util.List;
@Data
public class KeywordEnum {
    /**
     * 枚举参数的 key
     */
    private String keywordCode;
    /**
     * 枚举参数值范围列表
     */
    private List<String> enumValueList;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/MessageTemplate.java
New file
@@ -0,0 +1,36 @@
package com.stylefeng.guns.modular.system.util.weChat.model;
import lombok.Data;
import java.util.List;
/**
 * 消息模板
 */
@Data
public class MessageTemplate {
    /**
     * 添加至帐号下的模板 id,发送小程序订阅消息时所需
     */
    private String priTmplId;
    /**
     * 模版标题
     */
    private String title;
    /**
     * 模版内容
     */
    private String content;
    /**
     * 模板内容示例
     */
    private String example;
    /**
     * 模版类型,2 为一次性订阅,3 为长期订阅
     */
    private Integer type;
    /**
     * 枚举参数值范围
     */
    private List<KeywordEnum> keywordEnumValueList;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/PubTemplateKeywords.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.util.weChat.model;
import lombok.Data;
/**
 * 公共消息模板关键字
 */
@Data
public class PubTemplateKeywords {
    /**
     * 关键词 id,选用模板时需要
     */
    private Integer kid;
    /**
     * 关键词内容
     */
    private String name;
    /**
     * 关键词内容对应的示例
     */
    private String example;
    /**
     * 参数类型
     */
    private String rule;
}
guns-admin/src/main/java/com/stylefeng/guns/modular/system/util/weChat/model/PubTemplatetitles.java
New file
@@ -0,0 +1,26 @@
package com.stylefeng.guns.modular.system.util.weChat.model;
import lombok.Data;
/**
 * 功能模板
 */
@Data
public class PubTemplatetitles {
    /**
     * 模版标题 id
     */
    private Integer tid;
    /**
     * 模版标题
     */
    private String title;
    /**
     * 模版类型,2 为一次性订阅,3 为长期订阅
     */
    private Integer type;
    /**
     * 模版所属类目 id
     */
    private Integer categoryId;
}
Diff truncated after the above file
guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/DeptWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/DictWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/LogWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/MenuWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/NoticeWrapper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/PointLocation.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/RoleWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/UserWarpper.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/HousingDemandReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/RegisterAccountReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/ReportHouseResourceReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/ReportHousingDemandReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/SearchHouseResourceReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/req/SearchHousingDemandReq.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/AppletLoginRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/BannerRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/ContactInformationRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/DistrictHouseResourceNumberRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/DistrictRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/EncyclopedicKnowledgeInfoRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/EncyclopedicKnowledgeRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/HouseResourceInfoRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/HousingDemandInfoRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHouseResourceListRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHouseResourceRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHousingDemandListRes.java guns-admin/src/main/java/com/stylefeng/guns/modular/system/warpper/res/SearchHousingDemandRes.java guns-admin/src/main/resources/META-INF/spring-devtools.properties guns-admin/src/main/resources/application-dev.yml guns-admin/src/main/resources/application-produce.yml guns-admin/src/main/resources/application.yml guns-admin/src/main/resources/ehcache.xml guns-admin/src/main/resources/logback-spring.xml guns-admin/src/main/webapp/WEB-INF/view/404.html guns-admin/src/main/webapp/WEB-INF/view/blackboard.html guns-admin/src/main/webapp/WEB-INF/view/code/code.html guns-admin/src/main/webapp/WEB-INF/view/common/_container.html guns-admin/src/main/webapp/WEB-INF/view/common/_right.html guns-admin/src/main/webapp/WEB-INF/view/common/_tab.html guns-admin/src/main/webapp/WEB-INF/view/common/_theme.html guns-admin/src/main/webapp/WEB-INF/view/common/tags/NameCon.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/SelectCon.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/TimeCon.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/avatar.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/button.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/input.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/select.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/table.tag guns-admin/src/main/webapp/WEB-INF/view/common/tags/tag_tips guns-admin/src/main/webapp/WEB-INF/view/common/tags/uploadImg.tag guns-admin/src/main/webapp/WEB-INF/view/index.html guns-admin/src/main/webapp/WEB-INF/view/login.html guns-admin/src/main/webapp/WEB-INF/view/system/appUser/appUser.html guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner.html guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_add.html guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/banner/banner_info.html guns-admin/src/main/webapp/WEB-INF/view/system/banner/clickBannerUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/code/code.html guns-admin/src/main/webapp/WEB-INF/view/system/coupon/clickBannerUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon.html guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_add.html guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/coupon/coupon_info.html guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/clickUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity.html guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_add.html guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/couponActivity/couponActivity_info.html guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept.html guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_add.html guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict.html guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_add.html guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/exposureCrowd/exposureCrowd.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStation/gasStation.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_add.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_gasStation.html guns-admin/src/main/webapp/WEB-INF/view/system/gasStationActivity/gasStationActivity_iconSet.html guns-admin/src/main/webapp/WEB-INF/view/system/goods/goods.html guns-admin/src/main/webapp/WEB-INF/view/system/html/html.html guns-admin/src/main/webapp/WEB-INF/view/system/icon/clickIconUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon.html guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_add.html guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/icon/icon_info.html guns-admin/src/main/webapp/WEB-INF/view/system/log/log.html guns-admin/src/main/webapp/WEB-INF/view/system/log/login_log.html guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu.html guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_add.html guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice.html guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_add.html guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/oilPrice/oilPrice.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/clickPointActivityUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity_add.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/pointActivity_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/prizeList.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/receivePrizeList.html guns-admin/src/main/webapp/WEB-INF/view/system/pointActivity/taskList.html guns-admin/src/main/webapp/WEB-INF/view/system/role/role.html guns-admin/src/main/webapp/WEB-INF/view/system/role/role_add.html guns-admin/src/main/webapp/WEB-INF/view/system/role/role_assign.html guns-admin/src/main/webapp/WEB-INF/view/system/role/role_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/clickSalesPromotionUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/gasStationOilPrice_iconSet.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_add.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_info.html guns-admin/src/main/webapp/WEB-INF/view/system/salesPromotion/salesPromotion_mainInfo.html guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings.html guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings_add.html guns-admin/src/main/webapp/WEB-INF/view/system/shareAppletSettings/shareAppletSettings_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/constant.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponActivityInfo.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponActivityStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponPayStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/couponStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/downgrade.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/equityDetails.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/pageViewsStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/pointActivityStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/salesPromotionStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/taskStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/upgrade.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/vipLevelNumberSummaryGraph.html guns-admin/src/main/webapp/WEB-INF/view/system/statistics/vipLevelStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/subscribeMessage/subscribeMessage.html guns-admin/src/main/webapp/WEB-INF/view/system/subscribeMessage/subscribeMessageUser.html guns-admin/src/main/webapp/WEB-INF/view/system/sysOperationLog/sysOperationLog.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/backConfigure.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/homeSystemConfigure.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/phoneSystemConfigure.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/shareApplets.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/signSystemConfigure.html guns-admin/src/main/webapp/WEB-INF/view/system/systemConfigure/vipCycle.html guns-admin/src/main/webapp/WEB-INF/view/system/task/clickTaskUserList.html guns-admin/src/main/webapp/WEB-INF/view/system/task/task.html guns-admin/src/main/webapp/WEB-INF/view/system/task/task_add.html guns-admin/src/main/webapp/WEB-INF/view/system/task/task_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/task/task_info.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user_add.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user_chpwd.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user_roleassign.html guns-admin/src/main/webapp/WEB-INF/view/system/user/user_view.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/viewSubCodes.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannelStatistics.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannelStatisticsInfo.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel_add.html guns-admin/src/main/webapp/WEB-INF/view/system/vipChannel/vipChannel_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/vipGrowthRules/vipGrowthRules.html guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction.html guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction_add.html guns-admin/src/main/webapp/WEB-INF/view/system/vipJurisdiction/vipJurisdiction_edit.html guns-admin/src/main/webapp/WEB-INF/view/system/vipLevel/vipLevel.html guns-admin/src/main/webapp/WEB-INF/view/updatePass.html guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.css guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.css.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/css/bootstrap-select.min.css guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/bootstrap-select.min.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-am_ET.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ar_AR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-bg_BG.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-cs_CZ.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-da_DK.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-de_DE.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-en_US.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_CL.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-es_ES.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-et_EE.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-eu.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fa_IR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fi_FI.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-fr_FR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hr_HR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-hu_HU.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-id_ID.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-it_IT.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ja_JP.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-kh_KM.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ko_KR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lt_LT.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-lv_LV.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nb_NO.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-nl_NL.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pl_PL.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_BR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-pt_PT.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ro_RO.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ru_RU.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sk_SK.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sl_SI.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-sv_SE.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-tr_TR.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-ua_UA.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-vi_VN.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_CN.min.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.js guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.js.map guns-admin/src/main/webapp/static/bootstrap-select-1.13.0/js/i18n/defaults-zh_TW.min.js guns-admin/src/main/webapp/static/css/_fstyle.css guns-admin/src/main/webapp/static/css/bootstrap-rtl.css guns-admin/src/main/webapp/static/css/bootstrap.min.css guns-admin/src/main/webapp/static/css/font-awesome.css guns-admin/src/main/webapp/static/css/font-awesome.min.css guns-admin/src/main/webapp/static/css/login.css guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-1.png guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-3.png guns-admin/src/main/webapp/static/css/patterns/header-profile.png guns-admin/src/main/webapp/static/css/patterns/shattered.png guns-admin/src/main/webapp/static/css/plugins/bootstrap-table/bootstrap-table.min.css guns-admin/src/main/webapp/static/css/plugins/bootstrap-treetable/bootstrap-treetable.css guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite.png guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite@2x.png guns-admin/src/main/webapp/static/css/plugins/chosen/chosen.css guns-admin/src/main/webapp/static/css/plugins/iCheck/custom.css guns-admin/src/main/webapp/static/css/plugins/iCheck/green.png guns-admin/src/main/webapp/static/css/plugins/iCheck/green@2x.png guns-admin/src/main/webapp/static/css/plugins/images/sprite-skin-flat.png guns-admin/src/main/webapp/static/css/plugins/validate/bootstrapValidator.min.css guns-admin/src/main/webapp/static/css/plugins/webuploader/webuploader.css guns-admin/src/main/webapp/static/css/plugins/ztree/demo.css guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_close.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_open.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/2.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/3.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/4.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/5.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/6.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/7.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/8.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/9.png guns-admin/src/main/webapp/static/css/plugins/ztree/img/line_conn.gif guns-admin/src/main/webapp/static/css/plugins/ztree/img/loading.gif guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.gif guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.png guns-admin/src/main/webapp/static/css/plugins/ztree/zTreeStyle.css guns-admin/src/main/webapp/static/css/style.css guns-admin/src/main/webapp/static/excel/公告导入模板.xlsx guns-admin/src/main/webapp/static/favicon.ico guns-admin/src/main/webapp/static/fonts/FontAwesome.otf guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.eot guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.svg guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.ttf guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff2 guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.eot guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.svg guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2 guns-admin/src/main/webapp/static/img/1@3x.png guns-admin/src/main/webapp/static/img/20211230154035.png guns-admin/src/main/webapp/static/img/NoPIC.png guns-admin/src/main/webapp/static/img/backgroundImg.jpg guns-admin/src/main/webapp/static/img/bg.png guns-admin/src/main/webapp/static/img/boy.gif guns-admin/src/main/webapp/static/img/girl.gif guns-admin/src/main/webapp/static/img/icons.png guns-admin/src/main/webapp/static/img/loading-upload.gif guns-admin/src/main/webapp/static/img/locked.png guns-admin/src/main/webapp/static/img/logo.png guns-admin/src/main/webapp/static/img/logo1.png guns-admin/src/main/webapp/static/img/shangchuanpic.png guns-admin/src/main/webapp/static/img/signTypeOne.png guns-admin/src/main/webapp/static/img/signTypeTwo.png guns-admin/src/main/webapp/static/img/user.png guns-admin/src/main/webapp/static/img/yuansu.jpg guns-admin/src/main/webapp/static/imge/Avatar@2x.png guns-admin/src/main/webapp/static/imge/add.png guns-admin/src/main/webapp/static/imge/coupon-bg@2x.png guns-admin/src/main/webapp/static/imge/pos@x.png guns-admin/src/main/webapp/static/imge/subtract.png guns-admin/src/main/webapp/static/imge/zhekou@x.png guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.css guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.css.map guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.min.css guns-admin/src/main/webapp/static/js/Colorpicker/css/bootstrap-colorpicker.min.css.map guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.js guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.js.map guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.min.js guns-admin/src/main/webapp/static/js/Colorpicker/js/bootstrap-colorpicker.min.js.map guns-admin/src/main/webapp/static/js/bootstrap.min.js guns-admin/src/main/webapp/static/js/common/DateUtils.js guns-admin/src/main/webapp/static/js/common/Feng.js guns-admin/src/main/webapp/static/js/common/ajax-object.js guns-admin/src/main/webapp/static/js/common/bootstrap-table-object.js guns-admin/src/main/webapp/static/js/common/select-list-object.js guns-admin/src/main/webapp/static/js/common/tree-table-object.js guns-admin/src/main/webapp/static/js/common/web-upload-image.js guns-admin/src/main/webapp/static/js/common/web-upload-object.js guns-admin/src/main/webapp/static/js/common/ztree-object.js guns-admin/src/main/webapp/static/js/contabs.js guns-admin/src/main/webapp/static/js/content.js guns-admin/src/main/webapp/static/js/hplus.js guns-admin/src/main/webapp/static/js/html2canvas.js guns-admin/src/main/webapp/static/js/jquery.min.js guns-admin/src/main/webapp/static/js/jquery.min.map guns-admin/src/main/webapp/static/js/jquery.qrcode.js guns-admin/src/main/webapp/static/js/jquery.qrcode.min.js guns-admin/src/main/webapp/static/js/layui/css/layui.css guns-admin/src/main/webapp/static/js/layui/css/modules/code.css guns-admin/src/main/webapp/static/js/layui/css/modules/laydate/default/laydate.css guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/icon-ext.png guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/icon.png guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/layer.css guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-0.gif guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-1.gif guns-admin/src/main/webapp/static/js/layui/css/modules/layer/default/loading-2.gif guns-admin/src/main/webapp/static/js/layui/font/iconfont.eot guns-admin/src/main/webapp/static/js/layui/font/iconfont.svg guns-admin/src/main/webapp/static/js/layui/font/iconfont.ttf guns-admin/src/main/webapp/static/js/layui/font/iconfont.woff guns-admin/src/main/webapp/static/js/layui/font/iconfont.woff2 guns-admin/src/main/webapp/static/js/layui/layui.js guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table-mobile.min.js guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table.min.js guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.js guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js guns-admin/src/main/webapp/static/js/plugins/bootstrap-treetable/bootstrap-treetable.js guns-admin/src/main/webapp/static/js/plugins/chosen/chosen.jquery.js guns-admin/src/main/webapp/static/js/plugins/iCheck/icheck.min.js guns-admin/src/main/webapp/static/js/plugins/laydate/laydate.js guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.eot guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.svg guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.ttf guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.woff guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/laydate.css guns-admin/src/main/webapp/static/js/plugins/layer/layer.js guns-admin/src/main/webapp/static/js/plugins/layer/mobile/layer.js guns-admin/src/main/webapp/static/js/plugins/layer/mobile/need/layer.css guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon-ext.png guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon.png guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/layer.css guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-0.gif guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-1.gif guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-2.gif guns-admin/src/main/webapp/static/js/plugins/metisMenu/jquery.metisMenu.js guns-admin/src/main/webapp/static/js/plugins/pace/pace.min.js guns-admin/src/main/webapp/static/js/plugins/slimscroll/jquery.slimscroll.min.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/emotion.css guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/emotion.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/0.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/bface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/cface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/fface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/jxface2.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/neweditor-tab-bg.png guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/tface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/wface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/emotion/images/yface.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.css guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.html guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/formula.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/formula/images/formula.png guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/image.css guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/image.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/close.png guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/upload1.png guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/image/images/upload2.png guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/link/link.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/map/map.html guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/map/map.js guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/center_focus.jpg guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/left_focus.jpg guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/none_focus.jpg guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/images/right_focus.jpg guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/video.css guns-admin/src/main/webapp/static/js/plugins/umeditor/dialogs/video/video.js guns-admin/src/main/webapp/static/js/plugins/umeditor/index.html guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/en.js guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/addimage.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/alldeletebtnhoverskin.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/alldeletebtnupskin.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/background.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/button.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/copy.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/deletedisable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/deleteenable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/imglabel.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/listbackground.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/localimage.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/music.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotateleftdisable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotateleftenable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotaterightdisable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/rotaterightenable.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/en/images/upload.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/copy.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/imglabel.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/localimage.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/music.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/images/upload.png guns-admin/src/main/webapp/static/js/plugins/umeditor/lang/zh-cn/zh-cn.js guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/css/umeditor.css guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/css/umeditor.min.css guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/caret.png guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/close.png guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/icons.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/icons.png guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/ok.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/pop-bg.png guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/spacer.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/themes/default/images/videologo.gif guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/jquery.min.js guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.eot guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.otf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.svg guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.ttf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/Symbola.woff guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/STIXFontLicense2010.txt guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.eot guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.svg guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.ttf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneral-webfont.woff guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.eot guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.svg guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.ttf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbol-webfont.woff guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.eot guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.svg guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.ttf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralbolita-webfont.woff guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.eot guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.svg guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.ttf guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/font/stixgeneral-bundle/stixgeneralitalic-webfont.woff guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.css guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.js guns-admin/src/main/webapp/static/js/plugins/umeditor/third-party/mathquill/mathquill.min.js guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.config.js guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.js guns-admin/src/main/webapp/static/js/plugins/umeditor/umeditor.min.js guns-admin/src/main/webapp/static/js/plugins/validate/additional-methods.min.js guns-admin/src/main/webapp/static/js/plugins/validate/bootstrapValidator.min.js guns-admin/src/main/webapp/static/js/plugins/validate/zh_CN.js guns-admin/src/main/webapp/static/js/plugins/wangEditor/wangEditor.js guns-admin/src/main/webapp/static/js/plugins/webuploader/Uploader.swf guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.css guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.fis.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.min.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.js guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.min.js guns-admin/src/main/webapp/static/js/plugins/ztree/jquery.ztree.all.min.js guns-admin/src/main/webapp/static/js/qrcode.js guns-admin/src/main/webapp/static/js/qrcode.min.js guns-admin/src/main/webapp/static/js/vue.js guns-admin/src/main/webapp/static/js/vue.min.js guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._avatar-vip@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._banner@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._bg@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._coupon-title@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._guanzhu@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._integral-title@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._jifen@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._jilu@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._kefu@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._qiandao@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._renwu@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._shangcheng@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._vx@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._xieyi@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._yinsi@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._youhui@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._youhuiquan@2x.png guns-admin/src/main/webapp/static/mine/__MACOSX/mine/._ziliao@2x.png guns-admin/src/main/webapp/static/mine/mine/LV1@2x.png guns-admin/src/main/webapp/static/mine/mine/avatar-vip@2x.png guns-admin/src/main/webapp/static/mine/mine/banner@2x.png guns-admin/src/main/webapp/static/mine/mine/bg@2x.png guns-admin/src/main/webapp/static/mine/mine/coin-small@2x.png guns-admin/src/main/webapp/static/mine/mine/coin@2x.png guns-admin/src/main/webapp/static/mine/mine/coupon-title@2x.png guns-admin/src/main/webapp/static/mine/mine/coupon-v2@2x.png guns-admin/src/main/webapp/static/mine/mine/coupon@2x.png guns-admin/src/main/webapp/static/mine/mine/customer@2x.png guns-admin/src/main/webapp/static/mine/mine/folllow@2x.png guns-admin/src/main/webapp/static/mine/mine/guanzhu@2x.png guns-admin/src/main/webapp/static/mine/mine/huangguan@2x.png guns-admin/src/main/webapp/static/mine/mine/integral-title@2x.png guns-admin/src/main/webapp/static/mine/mine/jifen@2x.png guns-admin/src/main/webapp/static/mine/mine/jilu@2x.png guns-admin/src/main/webapp/static/mine/mine/jinbi@2x.png guns-admin/src/main/webapp/static/mine/mine/jine@2x.png guns-admin/src/main/webapp/static/mine/mine/kefu@2x.png guns-admin/src/main/webapp/static/mine/mine/level-bg@2x.png guns-admin/src/main/webapp/static/mine/mine/member-protocol@2x.png guns-admin/src/main/webapp/static/mine/mine/my-coupon@2x.png guns-admin/src/main/webapp/static/mine/mine/order@2x.png guns-admin/src/main/webapp/static/mine/mine/protocol@2x.png guns-admin/src/main/webapp/static/mine/mine/qiandao@2x.png guns-admin/src/main/webapp/static/mine/mine/renwu@2x.png guns-admin/src/main/webapp/static/mine/mine/shangcheng@2x.png guns-admin/src/main/webapp/static/mine/mine/task@2x.png guns-admin/src/main/webapp/static/mine/mine/userinfo@2x.png guns-admin/src/main/webapp/static/mine/mine/vx@2x.png guns-admin/src/main/webapp/static/mine/mine/weixin@2x.png guns-admin/src/main/webapp/static/mine/mine/xieyi@2x.png guns-admin/src/main/webapp/static/mine/mine/yinsi@2x.png guns-admin/src/main/webapp/static/mine/mine/youhui@2x.png guns-admin/src/main/webapp/static/mine/mine/youhuiquan@2x.png guns-admin/src/main/webapp/static/mine/mine/zhengce@2x.png guns-admin/src/main/webapp/static/mine/mine/ziliao@2x.png guns-admin/src/main/webapp/static/modular/code/gen.js guns-admin/src/main/webapp/static/modular/flowable/expense/expense.js guns-admin/src/main/webapp/static/modular/flowable/expense/expense_info.js guns-admin/src/main/webapp/static/modular/flowable/process/process.js guns-admin/src/main/webapp/static/modular/flowable/process/process_info.js guns-admin/src/main/webapp/static/modular/system/appUser/appUser.js guns-admin/src/main/webapp/static/modular/system/banner/banner.js guns-admin/src/main/webapp/static/modular/system/banner/banner_info.js guns-admin/src/main/webapp/static/modular/system/banner/clickBannerUserList.js guns-admin/src/main/webapp/static/modular/system/code/code.js guns-admin/src/main/webapp/static/modular/system/coupon/clickCouponUserList.js guns-admin/src/main/webapp/static/modular/system/coupon/coupon.js guns-admin/src/main/webapp/static/modular/system/coupon/coupon_info.js guns-admin/src/main/webapp/static/modular/system/couponActivity/clickUserList.js guns-admin/src/main/webapp/static/modular/system/couponActivity/couponActivity.js guns-admin/src/main/webapp/static/modular/system/couponActivity/couponActivity_info.js guns-admin/src/main/webapp/static/modular/system/dept/dept.js guns-admin/src/main/webapp/static/modular/system/dept/dept_info.js guns-admin/src/main/webapp/static/modular/system/dict/dict.js guns-admin/src/main/webapp/static/modular/system/dict/dict_info.js guns-admin/src/main/webapp/static/modular/system/exposureCrowd/exposureCrowd.js guns-admin/src/main/webapp/static/modular/system/gasStation/gasStation.js guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity.js guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_gasStation.js guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_iconSet.js guns-admin/src/main/webapp/static/modular/system/gasStationActivity/gasStationActivity_info.js guns-admin/src/main/webapp/static/modular/system/goods/goods.js guns-admin/src/main/webapp/static/modular/system/html/html.js guns-admin/src/main/webapp/static/modular/system/icon/clickIconUserList.js guns-admin/src/main/webapp/static/modular/system/icon/icon.js guns-admin/src/main/webapp/static/modular/system/icon/icon_info.js guns-admin/src/main/webapp/static/modular/system/log/log.js guns-admin/src/main/webapp/static/modular/system/log/login_log.js guns-admin/src/main/webapp/static/modular/system/menu/menu.js guns-admin/src/main/webapp/static/modular/system/menu/menu_info.js guns-admin/src/main/webapp/static/modular/system/notice/notice.js guns-admin/src/main/webapp/static/modular/system/notice/notice_info.js guns-admin/src/main/webapp/static/modular/system/oilPrice/oilPrice.js guns-admin/src/main/webapp/static/modular/system/pointActivity/clickPointActivityUserList.js guns-admin/src/main/webapp/static/modular/system/pointActivity/pointActivity.js guns-admin/src/main/webapp/static/modular/system/pointActivity/pointActivity_info.js guns-admin/src/main/webapp/static/modular/system/pointActivity/prizeList.js guns-admin/src/main/webapp/static/modular/system/pointActivity/receivePrizeList.js guns-admin/src/main/webapp/static/modular/system/pointActivity/taskList.js guns-admin/src/main/webapp/static/modular/system/role/role.js guns-admin/src/main/webapp/static/modular/system/role/role_info.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/clickSalesPromotionUserList.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice_iconSet.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/gasStationOilPrice_info.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/salesPromotion.js guns-admin/src/main/webapp/static/modular/system/salesPromotion/salesPromotion_info.js guns-admin/src/main/webapp/static/modular/system/shareAppletSettings/shareAppletSettings.js guns-admin/src/main/webapp/static/modular/system/shareAppletSettings/shareAppletSettings_info.js guns-admin/src/main/webapp/static/modular/system/statistics/constant.js guns-admin/src/main/webapp/static/modular/system/statistics/couponActivityInfo.js guns-admin/src/main/webapp/static/modular/system/statistics/couponActivityStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/couponPayStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/couponStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/downgrade.js guns-admin/src/main/webapp/static/modular/system/statistics/equityDetails.js guns-admin/src/main/webapp/static/modular/system/statistics/pageViewsStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/pointActivityStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/salesPromotionStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/taskStatistics.js guns-admin/src/main/webapp/static/modular/system/statistics/upgrade.js guns-admin/src/main/webapp/static/modular/system/statistics/vipLevelNumberSummaryGraph.js guns-admin/src/main/webapp/static/modular/system/statistics/vipLevelStatistics.js guns-admin/src/main/webapp/static/modular/system/subscribeMessage/subscribeMessage.js guns-admin/src/main/webapp/static/modular/system/subscribeMessage/subscribeMessageUser.js guns-admin/src/main/webapp/static/modular/system/sysOperationLog/sysOperationLog.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/backConfigure.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/homeSystemConfigure.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/phoneSystemConfigure.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/shareApplets.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/signSystemConfigure.js guns-admin/src/main/webapp/static/modular/system/systemConfigure/vipCycle.js guns-admin/src/main/webapp/static/modular/system/task/clickTaskUserList.js guns-admin/src/main/webapp/static/modular/system/task/task.js guns-admin/src/main/webapp/static/modular/system/task/task_info.js guns-admin/src/main/webapp/static/modular/system/user/user.js guns-admin/src/main/webapp/static/modular/system/user/user_info.js guns-admin/src/main/webapp/static/modular/system/vipChannel/viewSubCodes.js guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannel.js guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannelStatistics.js guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannelStatisticsInfo.js guns-admin/src/main/webapp/static/modular/system/vipChannel/vipChannel_info.js guns-admin/src/main/webapp/static/modular/system/vipGrowthRules/vipGrowthRules.js guns-admin/src/main/webapp/static/modular/system/vipJurisdiction/vipJurisdiction.js guns-admin/src/main/webapp/static/modular/system/vipJurisdiction/vipJurisdiction_info.js guns-admin/src/main/webapp/static/modular/system/vipLevel/vipLevel.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/anchor/anchor.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/attachment.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_chm.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_default.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_doc.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_exe.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_jpg.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_mp3.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_mv.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_pdf.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_ppt.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_psd.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_rar.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_txt.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/fileTypeImages/icon_xls.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/alignicon.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/alignicon.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/file-icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/file-icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/image.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/progress.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/success.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/attachment/images/success.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/background.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/images/bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/background/images/success.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/chart.config.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/charts.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts0.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts1.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts2.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts3.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts4.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/charts/images/charts5.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/emotion.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/0.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/bface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/cface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/fface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/jxface2.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/neweditor-tab-bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/tface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/wface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/emotion/images/yface.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/gmap/gmap.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/help/help.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/image.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/alignicon.jpg guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/image.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/progress.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/success.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/image/images/success.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/insertframe/insertframe.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/internal.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/link/link.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/map/map.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/map/show.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/music/music.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/preview/preview.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/addimg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/brush.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/delimg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/delimgH.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/empty.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/emptyH.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/eraser.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/redo.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/redoH.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/scale.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/scaleH.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/size.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/undo.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/images/undoH.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/scrawl/scrawl.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/searchreplace/searchreplace.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/searchreplace/searchreplace.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/snapscreen/snapscreen.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/spechars/spechars.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/spechars/spechars.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/dragicon.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittable.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittd.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/table/edittip.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/config.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/bg.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre0.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre1.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre2.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre3.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/images/pre4.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/template/template.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/center_focus.jpg guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/file-icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/file-icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/image.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/left_focus.jpg guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/none_focus.jpg guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/progress.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/right_focus.jpg guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/success.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/images/success.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/video/video.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/webapp/webapp.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/fClipboard_ueditor.swf guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/imageUploader.swf guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/tangram.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/wordimage.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/dialogs/wordimage/wordimage.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/index.html guns-admin/src/main/webapp/static/ueditor1_4_3_3/jsp/config.json guns-admin/src/main/webapp/static/ueditor1_4_3_3/jsp/controller.jsp guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/en.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/addimage.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/alldeletebtnhoverskin.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/alldeletebtnupskin.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/background.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/button.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/copy.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/deletedisable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/deleteenable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/listbackground.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/localimage.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/music.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotateleftdisable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotateleftenable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotaterightdisable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/rotaterightenable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/en/images/upload.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/copy.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/localimage.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/music.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/images/upload.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/lang/zh-cn/zh-cn.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/css/ueditor.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/css/ueditor.min.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/dialogbase.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/anchor.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow_down.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/arrow_up.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/button-bg.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cancelbutton.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/charts.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_h.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_h.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_v.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/cursor_v.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/dialog-title-bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/filescan.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/highlighted.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons-all.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/icons.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/loaderror.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/loading.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/lock.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/neweditor-tab-bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/pagebreak.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/scale.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/sortable.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/spacer.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/sparator_v.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/table-cell-align.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/tangram-colorpicker.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/toolbar_bg.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/unhighlighted.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/upload.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/videologo.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/word.gif guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/default/images/wordpaste.png guns-admin/src/main/webapp/static/ueditor1_4_3_3/themes/iframe.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/SyntaxHighlighter/shCore.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/SyntaxHighlighter/shCoreDefault.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/codemirror/codemirror.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/codemirror/codemirror.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/mootools-adapter.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/mootools-adapter.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/prototype-adapter.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/prototype-adapter.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/standalone-framework.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/adapters/standalone-framework.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts-more.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts-more.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/highcharts.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/annotations.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/annotations.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/canvas-tools.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/canvas-tools.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/data.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/data.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/drilldown.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/drilldown.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/exporting.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/exporting.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/funnel.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/funnel.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/heatmap.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/heatmap.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/map.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/map.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/no-data-to-display.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/modules/no-data-to-display.src.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/dark-blue.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/dark-green.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/gray.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/grid.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/highcharts/themes/skies.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/jquery-1.10.2.min.map guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/snapscreen/UEditorSnapscreen.exe guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.eot guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.svg guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.ttf guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/font/vjs.woff guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.min.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video-js.swf guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video.dev.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/video-js/video.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/Uploader.swf guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.css guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.custom.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.custom.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.flashonly.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.flashonly.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.html5only.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.html5only.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.withoutimage.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/webuploader/webuploader.withoutimage.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/xss.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/third-party/zeroclipboard/ZeroClipboard.swf guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.all.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.all.min.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.config.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.parse.js guns-admin/src/main/webapp/static/ueditor1_4_3_3/ueditor.parse.min.js guns-admin/src/test/java/com/stylefeng/guns/GunsApplicationTest.java guns-admin/src/test/sql/test.sql guns-core/pom.xml guns-core/src/main/java/com/stylefeng/guns/core/CoreFlag.java guns-core/src/main/java/com/stylefeng/guns/core/aop/BaseControllerExceptionHandler.java guns-core/src/main/java/com/stylefeng/guns/core/base/controller/BaseController.java guns-core/src/main/java/com/stylefeng/guns/core/base/controller/GlobalController.java guns-core/src/main/java/com/stylefeng/guns/core/base/controller/GunsErrorView.java guns-core/src/main/java/com/stylefeng/guns/core/base/tips/ErrorTip.java guns-core/src/main/java/com/stylefeng/guns/core/base/tips/SuccessTip.java guns-core/src/main/java/com/stylefeng/guns/core/base/tips/Tip.java guns-core/src/main/java/com/stylefeng/guns/core/base/warpper/BaseControllerWarpper.java guns-core/src/main/java/com/stylefeng/guns/core/cache/BaseCacheFactory.java guns-core/src/main/java/com/stylefeng/guns/core/cache/CacheKit.java guns-core/src/main/java/com/stylefeng/guns/core/cache/EhcacheFactory.java guns-core/src/main/java/com/stylefeng/guns/core/cache/ICache.java guns-core/src/main/java/com/stylefeng/guns/core/cache/ILoader.java guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultFastjsonConfig.java guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultMultiConfig.java guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultProperties.java guns-core/src/main/java/com/stylefeng/guns/core/config/DefaultWebConfig.java guns-core/src/main/java/com/stylefeng/guns/core/config/properties/DruidProperties.java guns-core/src/main/java/com/stylefeng/guns/core/config/properties/MutiDataSourceProperties.java guns-core/src/main/java/com/stylefeng/guns/core/constant/IsMenu.java guns-core/src/main/java/com/stylefeng/guns/core/datascope/DataScope.java guns-core/src/main/java/com/stylefeng/guns/core/datascope/DataScopeInterceptor.java guns-core/src/main/java/com/stylefeng/guns/core/db/Db.java guns-core/src/main/java/com/stylefeng/guns/core/exception/GunsException.java guns-core/src/main/java/com/stylefeng/guns/core/exception/GunsExceptionEnum.java guns-core/src/main/java/com/stylefeng/guns/core/exception/ServiceExceptionEnum.java guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/DataSourceContextHolder.java guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/DynamicDataSource.java guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/annotion/DataSource.java guns-core/src/main/java/com/stylefeng/guns/core/mutidatasource/aop/MultiSourceExAop.java guns-core/src/main/java/com/stylefeng/guns/core/node/MenuNode.java guns-core/src/main/java/com/stylefeng/guns/core/node/ZTreeNode.java guns-core/src/main/java/com/stylefeng/guns/core/page/PageBT.java guns-core/src/main/java/com/stylefeng/guns/core/page/PageInfoBT.java guns-core/src/main/java/com/stylefeng/guns/core/qr/ImgQrTool.java guns-core/src/main/java/com/stylefeng/guns/core/qr/MatrixToImageConfig.java guns-core/src/main/java/com/stylefeng/guns/core/qr/MatrixToImageWriter.java guns-core/src/main/java/com/stylefeng/guns/core/qr/QrImage.java guns-core/src/main/java/com/stylefeng/guns/core/support/BasicType.java guns-core/src/main/java/com/stylefeng/guns/core/support/BeanKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/ClassKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/CollectionKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/DateTime.java guns-core/src/main/java/com/stylefeng/guns/core/support/DateTimeKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/HexKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/HttpKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/ObjectKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/PageKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/StrKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/WafKit.java guns-core/src/main/java/com/stylefeng/guns/core/support/WafRequestWrapper.java guns-core/src/main/java/com/stylefeng/guns/core/support/exception/ToolBoxException.java guns-core/src/main/java/com/stylefeng/guns/core/util/Convert.java guns-core/src/main/java/com/stylefeng/guns/core/util/DateUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/FileUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/HttpSessionHolder.java guns-core/src/main/java/com/stylefeng/guns/core/util/IdGenerator.java guns-core/src/main/java/com/stylefeng/guns/core/util/MD5Util.java guns-core/src/main/java/com/stylefeng/guns/core/util/NumUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/PingYinUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/RenderUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/ResKit.java guns-core/src/main/java/com/stylefeng/guns/core/util/SimpleContrast.java guns-core/src/main/java/com/stylefeng/guns/core/util/SpringContextHolder.java guns-core/src/main/java/com/stylefeng/guns/core/util/SqlUtil.java guns-core/src/main/java/com/stylefeng/guns/core/util/ToolUtil.java guns-core/src/main/java/com/stylefeng/guns/core/xss/XssFilter.java guns-core/src/main/java/com/stylefeng/guns/core/xss/XssHttpServletRequestWrapper.java guns-core/src/main/resources/META-INF/spring.factories guns-core/src/main/resources/default-config.properties guns-generator/pom.xml guns-generator/src/main/java/com/stylefeng/guns/generator/action/GunsCodeGenerator.java guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/AbstractGeneratorConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/GunsGeneratorConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/action/config/WebGeneratorConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/action/model/GenQo.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/SimpleTemplateEngine.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/base/AbstractTemplateEngine.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/base/GunsTemplateEngine.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ContextConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ControllerConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/DaoConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/Menu.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/PageConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/ServiceConfig.java guns-generator/src/main/java/com/stylefeng/guns/generator/engine/config/SqlConfig.java guns-generator/src/main/resources/gunsTemplate/advanced/Controller.java.btl guns-generator/src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl guns-generator/src/main/resources/gunsTemplate/advanced/page.html.btl guns-generator/src/main/resources/gunsTemplate/advanced/page.js.btl guns-generator/src/main/resources/gunsTemplate/advanced/page_add.html.btl guns-generator/src/main/resources/gunsTemplate/advanced/page_edit.html.btl guns-generator/src/main/resources/gunsTemplate/advanced/page_info.js.btl pom.xml rental_house_applet.sql