xuhy
2023-02-27 e180e151ee8369fcff917d878b3fb15b72d06d31
Merge remote-tracking branch 'origin/master'
2个文件已删除
529个文件已添加
25个文件已修改
115407 ■■■■■ 已修改文件
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverWorkController.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/ImgController.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/OrderController.java 198 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/SystemConfigController.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/CancelOrderMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/OrderTransferMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/RevenueMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/WeatherCityMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CancelOrderMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderTransferMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RevenueMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/WeatherCityMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CancelOrder.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Order.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/OrderTransfer.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Revenue.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/WeatherCity.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICancelOrderService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderPositionService.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderService.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderTransferService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IRevenueService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IWeatherCityService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CancelOrderServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java 395 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderTransferServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/WeatherCityServiceImpl.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/ALiApiUtil.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/ChinaMobileUtil.java 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/GaoDe/MapUtil.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/GaoDe/model/District.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/JuHeUtil.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/PayMoneyUtil.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/PushUtil.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/httpClinet/HttpClientUtil.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherCityInfo.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherRes.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherUtil.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderEndAddressWarpper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderPriceWarpper.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/ProcessOperationsWarpper.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/PushOrderInfoWarpper.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/resources/logback-spring.xml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/test/java/com.supersavedriving.driver/GunsApplicationTest.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
super_save_driving.sql 4383 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/pom.xml 261 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/GunsApplication.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/GunsServletInitializer.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/EhCacheConfig.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/RedisConfig.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/SpringSessionConfig.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/SwaggerConfig.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/datasource/MultiDataSourceConfig.java 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/datasource/SingleDataSourceConfig.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/properties/BeetlProperties.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/properties/GunsProperties.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/BeetlConfig.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/ShiroConfig.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/WebConfig.java 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/aop/GlobalExceptionHandler.java 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/aop/LogAop.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/aop/PermissionAop.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/beetl/BeetlConfiguration.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/beetl/ShiroExt.java 186 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/BussinessLog.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/Permission.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/ServiceLog.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/aspect/ServiceLogAspect.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/Const.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/DatasourceEnum.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/JwtConstants.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/cache/Cache.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/cache/CacheKey.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DeleteDict.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DeptDict.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DictMap.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/LogDict.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/MenuDict.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/NoticeMap.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/RoleDict.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/UserDict.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/base/AbstractDictMap.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/base/SystemDict.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/factory/DictFieldWarpperFactory.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/ConstantFactory.java 335 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/IConstantFactory.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/MutiStrFactory.java 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/PageFactory.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/BizLogType.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/ExpenseState.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/LogSucceed.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/LogType.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/ManagerStatus.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/MenuOpenStatus.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/MenuStatus.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/Order.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/exception/BizExceptionEnum.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/exception/InvalidKaptchaException.java 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/intercept/GunsUserFilter.java 105 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/intercept/RestApiInteceptor.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/intercept/SessionHolderInterceptor.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/listener/ConfigListener.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/LogManager.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/LogObjectHolder.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/factory/LogFactory.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/factory/LogTaskFactory.java 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/ShiroDbRealm.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/ShiroKit.java 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/ShiroUser.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/check/ICheck.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/check/PermissionCheckFactory.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/check/PermissionCheckManager.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/factory/IShiro.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/factory/ShiroFactroy.java 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/tag/DictSelectorTag.java 201 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/ApiMenuFilter.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/Contrast.java 211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/JwtTokenUtil.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/KaptchaUtil.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/ApiController.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/HtmlController.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/controller/CodeController.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/factory/DefaultTemplateFactory.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/service/TableService.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthIntercepter.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthService.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthenticationKit.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/Configuration.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/HMACSHA1.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/HashKit.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/UrlEncoderUtils.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/BlackboardController.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/DeptController.java 164 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/DictController.java 142 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/KaptchaController.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LogController.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LoginController.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LoginLogController.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/MenuController.java 244 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/NoticeController.java 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/RoleController.java 230 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/UserMgrController.java 373 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AppUserMapper.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DeptMapper.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DictMapper.java 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/HtmlMapper.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/LoginLogMapper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/MenuMapper.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/NoticeMapper.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/OperationLogMapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RegionMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RelationMapper.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RoleMapper.java 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/UserMapper.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AppUserMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DeptMapper.xml 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/DictMapper.xml 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/HtmlMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/LoginLogMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/MenuMapper.xml 177 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/NoticeMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/OperationLogMapper.xml 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/RegionMapper.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/RelationMapper.xml 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/RoleMapper.xml 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/UserMapper.xml 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/factory/UserFactory.java 54 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/AppUser.java 103 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Dept.java 140 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Dict.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Html.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/LoginLog.java 128 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Menu.java 208 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Notice.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/OperationLog.java 154 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Region.java 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Relation.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Role.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/User.java 232 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAppUserService.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDeptService.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDictService.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IHtmlService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/ILoginLogService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IMenuService.java 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/INoticeService.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IOperationLogService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IRelationService.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IRoleService.java 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IUserService.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java 156 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DeptServiceImpl.java 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DictServiceImpl.java 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/HtmlServiceImpl.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/LoginLogServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/MenuServiceImpl.java 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/NoticeServiceImpl.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OperationLogServiceImpl.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/RelationServiceImpl.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/RoleServiceImpl.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/UserServiceImpl.java 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ManagerUser.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ReqAddManager.java 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ReqEditManager.java 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/UserDto.java 153 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ALiApiUtil.java 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ALiSendSms.java 123 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ChinaMobileUtil.java 133 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/DateUtil.java 135 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/GDFalconUtil.java 226 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/GeodesyUtil.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/JGPushUtil.java 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/JuHeUtil.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MD5AndKL.java 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/PayMoneyUtil.java 809 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/RedisUtil.java 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ResultUtil.java 187 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/SystemException.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/UUIDUtil.java 78 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/httpClinet/HttpClientUtil.java 269 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/httpClinet/HttpResult.java 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/AES.java 72 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/AesException.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/ByteGroup.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/PKCS7Encoder.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/SHA1.java 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/SubscribeMessageUtil.java 264 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXBizMsgCrypt.java 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXBizMsgCryptTest.java 147 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXCore.java 52 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WeChatUtil.java 415 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WxPKCS7Encoder.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/XMLParse.java 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/Category.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/Code2Session.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/KeywordEnum.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/MessageTemplate.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/PubTemplateKeywords.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/PubTemplatetitles.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/ActivityWarpper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/BaseWarpper.java 171 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DeptWarpper.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DictWarpper.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DriverInfoWarpper.java 359 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/HomeWarpper.java 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/LogWarpper.java 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/LoginWarpper.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/MenuWarpper.java 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/MoneyInfoWarpper.java 229 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/NoticeWrapper.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderEvaluateWarpper.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderInfoWarpper.java 489 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderListWarpper.java 227 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderStatusWarpper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrdersWarpper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/RegisteredWarpper.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/ResponseWarpper.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/RoleWarpper.java 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/SignInToRegister.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/SystemNoticeWarpper.java 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/UserWarpper.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/VersionWarpper.java 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/WithdrawalWarpper.java 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/resources/META-INF/spring-devtools.properties 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/resources/application.yml 131 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/resources/ehcache.xml 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/resources/logback-spring.xml 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/resources/redis.properties 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/404.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/blackboard.html 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/code/code.html 101 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/_container.html 71 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/_right.html 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/_tab.html 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/_theme.html 84 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/NameCon.tag 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/SelectCon.tag 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/TimeCon.tag 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/avatar.tag 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/button.tag 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/input.tag 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/select.tag 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/table.tag 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/tag_tips 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/index.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/login.html 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/code/code.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_add.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_edit.html 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_add.html 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_edit.html 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/log/log.html 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/log/login_log.html 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_add.html 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_edit.html 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice.html 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_add.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_edit.html 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role.html 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_add.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_assign.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_edit.html 47 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user.html 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_add.html 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_chpwd.html 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_edit.html 60 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_roleassign.html 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_view.html 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/_fstyle.css 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/bootstrap-rtl.css 1468 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/bootstrap.min.css 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/font-awesome.css 2026 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/font-awesome.min.css 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/login.css 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-1.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-3.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/patterns/header-profile.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/patterns/shattered.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/bootstrap-table/bootstrap-table.min.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/bootstrap-treetable/bootstrap-treetable.css 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen.css 423 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/iCheck/custom.css 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/iCheck/green.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/iCheck/green@2x.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/images/sprite-skin-flat.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/validate/bootstrapValidator.min.css 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/webuploader/webuploader.css 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/demo.css 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_close.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_open.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/2.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/3.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/4.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/5.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/6.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/7.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/8.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/9.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/line_conn.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/loading.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/plugins/ztree/zTreeStyle.css 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/css/style.css 7897 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/favicon.ico 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/FontAwesome.otf 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.svg 640 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff2 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.eot 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.svg 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/bg.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/boy.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/girl.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/icons.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/loading-upload.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/locked.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/img/user.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/bootstrap.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/DateUtils.js 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/Feng.js 196 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/ajax-object.js 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/bootstrap-table-object.js 134 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/select-list-object.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/tree-table-object.js 136 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/web-upload-object.js 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/common/ztree-object.js 94 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/contabs.js 339 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/content.js 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/hplus.js 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/jquery.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/jquery.min.map 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table-mobile.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table.min.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.js 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-treetable/bootstrap-treetable.js 308 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/chosen/chosen.jquery.js 1211 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/iCheck/icheck.min.js 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/laydate.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.eot 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.svg 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.ttf 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.woff 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/laydate.css 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/layer.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/mobile/layer.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/mobile/need/layer.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon-ext.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon.png 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/layer.css 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-0.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-1.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-2.gif 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/metisMenu/jquery.metisMenu.js 120 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/pace/pace.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/slimscroll/jquery.slimscroll.min.js 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/validate/additional-methods.min.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/validate/bootstrapValidator.min.js 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/validate/zh_CN.js 370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/wangEditor/wangEditor.js 3967 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/Uploader.swf 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.css 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.js 6502 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.fis.js 8083 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.js 4622 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.js 6030 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.js 8106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.min.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.js 5026 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.js 8012 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.min.js 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.js 4993 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.min.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/js/plugins/ztree/jquery.ztree.all.min.js 165 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/code/gen.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/flowable/expense/expense.js 93 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/flowable/expense/expense_info.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/flowable/process/process.js 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/flowable/process/process_info.js 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/code/code.js 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/dept/dept.js 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/dept/dept_info.js 182 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/dict/dict.js 104 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/dict/dict_info.js 118 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/log/log.js 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/log/login_log.js 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/menu/menu.js 119 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/menu/menu_info.js 175 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/notice/notice.js 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/notice/notice_info.js 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/role/role.js 125 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/role/role_info.js 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/user/user.js 207 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-admin/src/main/webapp/static/modular/system/user/user_info.js 290 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/pom.xml 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/CoreFlag.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/aop/BaseControllerExceptionHandler.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/BaseController.java 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/GlobalController.java 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/GunsErrorView.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/ErrorTip.java 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/SuccessTip.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/Tip.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/base/warpper/BaseControllerWarpper.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/cache/BaseCacheFactory.java 49 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/cache/CacheKit.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/cache/EhcacheFactory.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/cache/ICache.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/cache/ILoader.java 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultFastjsonConfig.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultMultiConfig.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultProperties.java 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultWebConfig.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/properties/DruidProperties.java 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/config/properties/MutiDataSourceProperties.java 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/constant/IsMenu.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/datascope/DataScope.java 50 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/datascope/DataScopeInterceptor.java 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/db/Db.java 108 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/exception/GunsException.java 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/exception/GunsExceptionEnum.java 59 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/exception/ServiceExceptionEnum.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/DataSourceContextHolder.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/DynamicDataSource.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/annotion/DataSource.java 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/aop/MultiSourceExAop.java 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/node/MenuNode.java 238 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/node/ZTreeNode.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/page/PageBT.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/page/PageInfoBT.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/qr/ImgQrTool.java 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/qr/MatrixToImageConfig.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/qr/MatrixToImageWriter.java 122 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/qr/QrImage.java 170 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/BasicType.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/BeanKit.java 508 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/ClassKit.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/CollectionKit.java 801 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/DateTime.java 67 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/DateTimeKit.java 665 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/HexKit.java 254 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/HttpKit.java 195 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/ObjectKit.java 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/PageKit.java 57 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/StrKit.java 1370 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/WafKit.java 114 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/WafRequestWrapper.java 149 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/support/exception/ToolBoxException.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/Convert.java 1061 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/DateUtil.java 250 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/FileUtil.java 73 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/HttpSessionHolder.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/IdGenerator.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/MD5Util.java 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/NumUtil.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/PingYinUtil.java 206 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/RenderUtil.java 32 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/ResKit.java 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/SimpleContrast.java 58 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/SpringContextHolder.java 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/SqlUtil.java 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/util/ToolUtil.java 582 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/xss/XssFilter.java 42 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/java/com/supersavedriving/user/core/xss/XssHttpServletRequestWrapper.java 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/resources/META-INF/spring.factories 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-core/src/main/resources/default-config.properties 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/pom.xml 35 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/GunsCodeGenerator.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/AbstractGeneratorConfig.java 109 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/GunsGeneratorConfig.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/WebGeneratorConfig.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/model/GenQo.java 297 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/SimpleTemplateEngine.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/base/AbstractTemplateEngine.java 116 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/base/GunsTemplateEngine.java 126 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ContextConfig.java 214 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ControllerConfig.java 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/DaoConfig.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/Menu.java 203 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/PageConfig.java 74 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ServiceConfig.java 91 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/SqlConfig.java 194 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/Controller.java.btl 96 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/page.html.btl 38 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/page.js.btl 102 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/page_add.html.btl 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/page_edit.html.btl 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/guns-generator/src/main/resources/gunsTemplate/advanced/page_info.js.btl 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
user/pom.xml 252 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverController.java
@@ -294,17 +294,22 @@
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper<PromotionWarpper> queryPromotionQRCode(HttpServletRequest request){
    public ResponseWarpper<PromotionWarpper> queryPromotionQRCode(HttpServletRequest request) {
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
            if (null == uid) {
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            PromotionWarpper promotionWarpper = driverService.queryPromotionQRCode(uid);
            return ResponseWarpper.success(promotionWarpper);
        }catch (Exception e){
        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/DriverWorkController.java
@@ -81,4 +81,8 @@
            return new ResponseWarpper(500, e.getMessage());
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/ImgController.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.driver.core.common.annotion.ServiceLog;
import com.supersavedriving.driver.core.util.ToolUtil;
import com.supersavedriving.driver.modular.system.model.Img;
import com.supersavedriving.driver.modular.system.service.IImgService;
@@ -23,8 +24,6 @@
@RequestMapping("")
public class ImgController {
    Logger logger = LoggerFactory.getLogger("ServiceLog");
    @Autowired
    private IImgService imgService;
@@ -32,38 +31,28 @@
    @ResponseBody
    @PostMapping("/base/img/querySysImg")
    @ServiceLog(name = "获取系统图片", url = "/base/img/querySysImg")
    @ApiOperation(value = "获取系统图片", tags = {"司机端-公共接口"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "数据类型(1=启动页)", name = "type", required = true, dataType = "int"),
    })
    public ResponseWarpper<List<BaseWarpper>> querySysImg(@RequestParam("type") Integer type){
        ResponseWarpper responseWarpper = null;
        if(ToolUtil.isEmpty(type)){
            responseWarpper = ResponseWarpper.success(ResultUtil.paranErr());
            return ResponseWarpper.success(ResultUtil.paranErr("type"));
        }
        if(ToolUtil.isNotEmpty(type)){
            try {
                List<Img> imgs = imgService.selectList(new EntityWrapper<Img>().eq("type", type));
                List<BaseWarpper> list = new ArrayList<>();
                for (Img img : imgs) {
                    BaseWarpper baseWarpper = new BaseWarpper();
                    baseWarpper.setId(img.getId());
                    baseWarpper.setPath(img.getImg());
                    list.add(baseWarpper);
                }
                responseWarpper = ResponseWarpper.success(list);
            }catch (Exception e){
                e.printStackTrace();
                responseWarpper = new ResponseWarpper(500, e.getMessage());
        try {
            List<Img> imgs = imgService.selectList(new EntityWrapper<Img>().eq("type", type));
            List<BaseWarpper> list = new ArrayList<>();
            for (Img img : imgs) {
                BaseWarpper baseWarpper = new BaseWarpper();
                baseWarpper.setId(img.getId().longValue());
                baseWarpper.setPath(img.getImg());
                list.add(baseWarpper);
            }
            return ResponseWarpper.success(list);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
        logger.debug("" +
                "\n接口地址:/base/img/querySysImg" +
                "\n接口名称:获取系统图片" +
                "\n请求参数:type:{}" +
                "\n响应结果:{}"
                , type, JSON.toJSONString(responseWarpper));
        return responseWarpper;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/OrderController.java
@@ -1,13 +1,11 @@
package com.supersavedriving.driver.modular.system.api;
import com.supersavedriving.driver.core.common.annotion.ServiceLog;
import com.supersavedriving.driver.core.util.ToolUtil;
import com.supersavedriving.driver.modular.system.service.IDriverService;
import com.supersavedriving.driver.modular.system.service.IOrderService;
import com.supersavedriving.driver.modular.system.util.ResultUtil;
import com.supersavedriving.driver.modular.system.warpper.AddOrderWarpper;
import com.supersavedriving.driver.modular.system.warpper.HallOrderList;
import com.supersavedriving.driver.modular.system.warpper.OrderInfoWarpper;
import com.supersavedriving.driver.modular.system.warpper.ResponseWarpper;
import com.supersavedriving.driver.modular.system.warpper.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
@@ -119,7 +117,7 @@
    @ResponseBody
    @PostMapping("/api/order/rejectionOrder")
    @ServiceLog(name = "司机拒绝接单", url = "/api/order/rejectionOrder")
    @ApiOperation(value = "司机拒绝接单", tags = {"司机端-首页"}, notes = "")
    @ApiOperation(value = "司机拒绝接单", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
@@ -148,7 +146,7 @@
    @ResponseBody
    @PostMapping("/api/order/receiveOrder")
    @ServiceLog(name = "司机接单操作", url = "/api/order/receiveOrder")
    @ApiOperation(value = "司机接单操作", tags = {"司机端-首页"}, notes = "")
    @ApiOperation(value = "司机接单操作", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
@@ -176,7 +174,7 @@
    @ResponseBody
    @PostMapping("/api/order/queryOrderInfo")
    @ServiceLog(name = "获取订单详情", url = "/api/order/queryOrderInfo")
    @ApiOperation(value = "获取订单详情", tags = {"司机端-首页"}, notes = "")
    @ApiOperation(value = "获取订单详情", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
@@ -200,15 +198,193 @@
    public ResponseWarpper driverProcessOperations(Long orderId, Integer state, HttpServletRequest request){
        if(null == orderId){
    @ResponseBody
    @PostMapping("/api/order/driverProcessOperations")
    @ServiceLog(name = "司机走订单流程", url = "/api/order/driverProcessOperations")
    @ApiOperation(value = "司机走订单流程", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper driverProcessOperations(ProcessOperationsWarpper processOperationsWarpper, HttpServletRequest request){
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.driverProcessOperations(uid, processOperationsWarpper);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/transferOrder")
    @ServiceLog(name = "司机转单操作", url = "/api/order/transferOrder")
    @ApiOperation(value = "司机转单操作", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(value = "原因", name = "cause", required = true, dataType = "string"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper transferOrder(Long orderId, String cause, HttpServletRequest request){
        if(ToolUtil.isEmpty(orderId)){
            return ResponseWarpper.success(ResultUtil.paranErr("orderId"));
        }
        if(null == state){
        if(ToolUtil.isEmpty(cause)){
            return ResponseWarpper.success(ResultUtil.paranErr("cause"));
        }
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.transferOrder(uid, orderId, cause);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/setOrderEndAddress")
    @ServiceLog(name = "司机修改订单终点", url = "/api/order/setOrderEndAddress")
    @ApiOperation(value = "司机修改订单终点", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper setOrderEndAddress(OrderEndAddressWarpper orderEndAddressWarpper, HttpServletRequest request){
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.setOrderEndAddress(uid, orderEndAddressWarpper);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/cancelTransferOrder")
    @ServiceLog(name = "司机取消转单操作", url = "/api/order/cancelTransferOrder")
    @ApiOperation(value = "司机取消转单操作", tags = {"司机端-我的订单"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper cancelTransferOrder(Long orderId, HttpServletRequest request){
        if(ToolUtil.isEmpty(orderId)){
            return ResponseWarpper.success(ResultUtil.paranErr("orderId"));
        }
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.cancelTransferOrder(uid, orderId);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/driverCancelOrder")
    @ServiceLog(name = "司机取消订单操作", url = "/api/order/driverCancelOrder")
    @ApiOperation(value = "司机取消订单操作", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(value = "原因", name = "cause", required = true, dataType = "string"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper driverCancelOrder(Long orderId, String cause, HttpServletRequest request){
        if(ToolUtil.isEmpty(orderId)){
            return ResponseWarpper.success(ResultUtil.paranErr("orderId"));
        }
        if(ToolUtil.isEmpty(cause)){
            return ResponseWarpper.success(ResultUtil.paranErr("cause"));
        }
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.driverCancelOrder(uid, orderId, cause);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/queryOrderPrice")
    @ServiceLog(name = "获取订单费用明细", url = "/api/order/queryOrderPrice")
    @ApiOperation(value = "获取订单费用明细", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper<OrderPriceWarpper> queryOrderPrice(Long orderId, HttpServletRequest request){
        if(ToolUtil.isEmpty(orderId)){
            return ResponseWarpper.success(ResultUtil.paranErr("orderId"));
        }
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            OrderPriceWarpper orderPriceWarpper = orderService.queryOrderPrice(uid, orderId);
            return ResponseWarpper.success(orderPriceWarpper);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/api/order/setOrderStatus")
    @ServiceLog(name = "服务完成后修改订单状态", url = "/api/order/setOrderStatus")
    @ApiOperation(value = "服务完成后修改订单状态", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "订单id", name = "orderId", required = true, dataType = "long"),
            @ApiImplicitParam(value = "107(线上支付),108(完成线下支付)", name = "state", required = true, dataType = "int"),
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper setOrderStatus(Long orderId, Integer state, HttpServletRequest request){
        if(ToolUtil.isEmpty(orderId)){
            return ResponseWarpper.success(ResultUtil.paranErr("orderId"));
        }
        if(ToolUtil.isEmpty(state)){
            return ResponseWarpper.success(ResultUtil.paranErr("state"));
        }
        try {
            Integer uid = driverService.getUserByRequset(request);
            if(null == uid){
                return ResponseWarpper.success(ResultUtil.tokenErr());
            }
            ResultUtil resultUtil = orderService.setOrderStatus(uid, orderId, state);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/api/SystemConfigController.java
New file
@@ -0,0 +1,52 @@
package com.supersavedriving.driver.modular.system.api;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.driver.core.common.annotion.ServiceLog;
import com.supersavedriving.driver.modular.system.model.SystemConfig;
import com.supersavedriving.driver.modular.system.service.ISystemConfigService;
import com.supersavedriving.driver.modular.system.warpper.ResponseWarpper;
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 pzb
* @Date 2023/2/25 11:53
*/
@RestController
@RequestMapping("")
public class SystemConfigController {
    @Autowired
    private ISystemConfigService systemConfigService;
    @ResponseBody
    @PostMapping("/base/config/queryTransferOrderConfig")
    @ServiceLog(name = "获取转单提醒时间配置", url = "/base/config/queryTransferOrderConfig")
    @ApiOperation(value = "获取转单提醒时间配置", tags = {"司机端-服务中"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "Authorization", value = "用户token(Bearer +token)", required = true, dataType = "String", paramType = "header", defaultValue = "Bearer eyJhbGciOiJIUzUxMiJ9.....")
    })
    public ResponseWarpper<Integer> queryTransferOrderConfig(){
        try {
            SystemConfig systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 1));
            JSONObject jsonObject = JSON.parseObject(systemConfig.getContent());
            Integer num5 = jsonObject.getInteger("num5");
            return ResponseWarpper.success(num5);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/CancelOrderMapper.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.driver.modular.system.model.CancelOrder;
public interface CancelOrderMapper extends BaseMapper<CancelOrder> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/OrderTransferMapper.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.driver.modular.system.model.OrderTransfer;
public interface OrderTransferMapper extends BaseMapper<OrderTransfer> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/RevenueMapper.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.driver.modular.system.model.Revenue;
public interface RevenueMapper extends BaseMapper<Revenue> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/WeatherCityMapper.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.driver.modular.system.model.WeatherCity;
public interface WeatherCityMapper extends BaseMapper<WeatherCity> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/CancelOrderMapper.xml
New file
@@ -0,0 +1,15 @@
<?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.supersavedriving.driver.modular.system.dao.CancelOrderMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.CancelOrder">
        <id column="id" property="id"/>
        <result column="orderId" property="orderId"/>
        <result column="userType" property="userType"/>
        <result column="userId" property="userId"/>
        <result column="cause" property="cause"/>
        <result column="status" property="status"/>
        <result column="createTime" property="createTime"/>
    </resultMap>
</mapper>
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/DriverMapper.xml
@@ -37,5 +37,14 @@
        <result column="remark" property="remark"/>
        <result column="isException" property="isException"/>
        <result column="createTime" property="createTime"/>
        <result column="provinceCode" property="provinceCode"/>
        <result column="provinceName" property="provinceName"/>
        <result column="cityCode" property="cityCode"/>
        <result column="cityName" property="cityName"/>
        <result column="areaCode" property="areaCode"/>
        <result column="areaName" property="areaName"/>
        <result column="commission" property="commission"/>
        <result column="wxCollectionCode" property="wxCollectionCode"/>
        <result column="zfbCollectionCode" property="zfbCollectionCode"/>
    </resultMap>
</mapper>
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderMapper.xml
@@ -13,6 +13,9 @@
        <result column="source" property="source" />
        <result column="agentId" property="agentId" />
        <result column="branchOfficeId" property="branchOfficeId" />
        <result column="orderTakingTime" property="orderTakingTime"/>
        <result column="goToAppointmentPointTime" property="goToAppointmentPointTime"/>
        <result column="arrivalTimeAtTheAppointmentPoint" property="arrivalTimeAtTheAppointmentPoint"/>
        <result column="startTime" property="startTime" />
        <result column="startAddress" property="startAddress" />
        <result column="startLat" property="startLat" />
@@ -46,9 +49,12 @@
        <result column="payMoney" property="payMoney" />
        <result column="discountedPrice" property="discountedPrice" />
        <result column="couponId" property="couponId" />
        <result column="discountAmount" property="discountAmount"/>
        <result column="discount" property="discount"/>
        <result column="payType" property="payType" />
        <result column="payTime" property="payTime" />
        <result column="hallOrder" property="hallOrder"/>
        <result column="startWaitTime" property="startWaitTime"/>
        <result column="state" property="state" />
        <result column="oldState" property="oldState"/>
        <result column="status" property="status" />
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/OrderTransferMapper.xml
New file
@@ -0,0 +1,16 @@
<?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.supersavedriving.driver.modular.system.dao.OrderTransferMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.OrderTransfer">
        <id column="id" property="id" />
        <result column="orderId" property="orderId" />
        <result column="oldDriverId" property="oldDriverId" />
        <result column="newDriverId" property="newDriverId" />
        <result column="cause" property="cause"/>
        <result column="status" property="status" />
        <result column="successTime" property="successTime" />
        <result column="createTime" property="createTime" />
    </resultMap>
</mapper>
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/RevenueMapper.xml
New file
@@ -0,0 +1,16 @@
<?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.supersavedriving.driver.modular.system.dao.RevenueMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.Revenue">
        <id column="id" property="id" />
        <result column="type" property="type" />
        <result column="userType" property="userType" />
        <result column="userId" property="userId" />
        <result column="orderId" property="orderId" />
        <result column="amount" property="amount" />
        <result column="createTime" property="createTime" />
    </resultMap>
</mapper>
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/dao/mapping/WeatherCityMapper.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.supersavedriving.driver.modular.system.dao.WeatherCityMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.driver.modular.system.model.WeatherCity">
        <id column="id" property="id" />
        <result column="province" property="province" />
        <result column="city" property="city" />
        <result column="district" property="district" />
    </resultMap>
</mapper>
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/CancelOrder.java
New file
@@ -0,0 +1,55 @@
package com.supersavedriving.driver.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 pzb
* @Date 2023/2/25 14:37
*/
@Data
@TableName("t_cancel_order")
public class CancelOrder {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 订单id
     */
    @TableField("orderId")
    private Long orderId;
    /**
     * 用户类型(1=用户,2=司机)
     */
    @TableField("userType")
    private Integer userType;
    /**
     * 用户id
     */
    @TableField("userId")
    private Integer userId;
    /**
     * 取消原因
     */
    @TableField("cause")
    private String cause;
    /**
     * 状态(1=正常,2=冻结,3=删除)
     */
    @TableField("status")
    private Integer status;
    /**
     * 添加时间
     */
    @TableField("createTime")
    private Date createTime;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Driver.java
@@ -177,4 +177,49 @@
     */
    @TableField("createTime")
    private Date createTime;
    /**
     * 加盟区域省编号
     */
    @TableField("provinceCode")
    private String provinceCode;
    /**
     * 加盟区域省名称
     */
    @TableField("provinceName")
    private String provinceName;
    /**
     * 加盟区域市编号
     */
    @TableField("cityCode")
    private String cityCode;
    /**
     * 加盟区域市名称
     */
    @TableField("cityName")
    private String cityName;
    /**
     * 加盟区域区编号
     */
    @TableField("areaCode")
    private String areaCode;
    /**
     * 加盟区域区名称
     */
    @TableField("areaName")
    private String areaName;
    /**
     * 佣金
     */
    @TableField("commission")
    private Double commission;
    /**
     * 微信收款码
     */
    @TableField("wxCollectionCode")
    private String wxCollectionCode;
    /**
     * 支付宝收款码
     */
    @TableField("zfbCollectionCode")
    private String zfbCollectionCode;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Order.java
@@ -63,6 +63,21 @@
    @TableField("branchOfficeId")
    private Integer branchOfficeId;
    /**
     * 接单时间
     */
    @TableField("orderTakingTime")
    private Date orderTakingTime;
    /**
     * 前往预约点时间
     */
    @TableField("goToAppointmentPointTime")
    private Date goToAppointmentPointTime;
    /**
     * 到达预约点时间
     */
    @TableField("arrivalTimeAtTheAppointmentPoint")
    private Date arrivalTimeAtTheAppointmentPoint;
    /**
     * 开始服务时间
     */
    @TableField("startTime")
@@ -211,7 +226,7 @@
     * 实际里程
     */
    @TableField("actualMileage")
    private Double actualMileage;
    private Integer actualMileage;
    /**
     * 支付金额
     */
@@ -228,6 +243,16 @@
    @TableField("couponId")
    private Integer couponId;
    /**
     * 折扣优惠金额
     */
    @TableField("discountAmount")
    private Double discountAmount;
    /**
     * 折扣0.01
     */
    @TableField("discount")
    private Double discount;
    /**
     * 支付类型(1=微信支付,2=余额支付,3=线下支付)
     */
    @TableField("payType")
@@ -243,7 +268,12 @@
    @TableField("hallOrder")
    private Integer hallOrder;
    /**
     * 订单状态(101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待评价,108=已完成,201=转单中,301=已取消)
     * 订单开始进入等待状态时间
     */
    @TableField("startWaitTime")
    private Date startWaitTime;
    /**
     * 订单状态(101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待支付,108=待评价,109=已完成,201=转单中,301=已取消,401=等待中)
     */
    @TableField("state")
    private Integer state;
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/OrderTransfer.java
New file
@@ -0,0 +1,60 @@
package com.supersavedriving.driver.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 pzb
* @Date 2023/2/25 13:40
*/
@Data
@TableName("t_order_transfer")
public class OrderTransfer {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 订单id
     */
    @TableField("orderId")
    private Long orderId;
    /**
     * 原司机id
     */
    @TableField("oldDriverId")
    private Integer oldDriverId;
    /**
     * 新司机id
     */
    @TableField("newDriverId")
    private Integer newDriverId;
    /**
     * 转单原因
     */
    @TableField("cause")
    private String cause;
    /**
     * 状态(1=正常,2=冻结,3=删除)
     */
    @TableField("status")
    private Integer status;
    /**
     * 转单成功时间
     */
    @TableField("successTime")
    private Date successTime;
    /**
     * 添加时间
     */
    @TableField("createTime")
    private Date createTime;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/Revenue.java
New file
@@ -0,0 +1,55 @@
package com.supersavedriving.driver.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 pzb
* @Date 2023/2/25 16:06
*/
@Data
@TableName("t_revenue")
public class Revenue {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 收入类型(1=订单收入,2=分佣收入)
     */
    @TableField("type")
    private Integer type;
    /**
     * 用户类型(1=用户,2=司机,3=代理商)
     */
    @TableField("userType")
    private Integer userType;
    /**
     * 用户id
     */
    @TableField("userId")
    private Integer userId;
    /**
     * 订单id
     */
    @TableField("orderId")
    private Long orderId;
    /**
     * 收入金额
     */
    @TableField("amount")
    private Double amount;
    /**
     * 添加时间
     */
    @TableField("createTime")
    private Date createTime;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/model/WeatherCity.java
New file
@@ -0,0 +1,38 @@
package com.supersavedriving.driver.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 pzb
* @Date 2023/2/25 10:56
*/
@Data
@TableName("t_weather_city")
public class WeatherCity {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.INPUT)
    @TableField("id")
    private Integer id;
    /**
     * 省
     */
    @TableField("province")
    private String province;
    /**
     * 市
     */
    @TableField("city")
    private String city;
    /**
     * 区
     */
    @TableField("district")
    private String district;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/ICancelOrderService.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.driver.modular.system.model.CancelOrder;
public interface ICancelOrderService extends IService<CancelOrder> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderPositionService.java
@@ -1,6 +1,5 @@
package com.supersavedriving.driver.modular.system.service;
import com.supersavedriving.driver.modular.system.util.ResultUtil;
import com.supersavedriving.driver.modular.system.warpper.DriverPositionWarpper;
import com.supersavedriving.driver.modular.system.warpper.OrderPositionWarpper;
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderService.java
@@ -3,10 +3,7 @@
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.driver.modular.system.model.Order;
import com.supersavedriving.driver.modular.system.util.ResultUtil;
import com.supersavedriving.driver.modular.system.warpper.AddOrderWarpper;
import com.supersavedriving.driver.modular.system.warpper.BaseWarpper;
import com.supersavedriving.driver.modular.system.warpper.HallOrderList;
import com.supersavedriving.driver.modular.system.warpper.OrderInfoWarpper;
import com.supersavedriving.driver.modular.system.warpper.*;
import java.util.List;
@@ -77,4 +74,79 @@
     * @throws Exception
     */
    OrderInfoWarpper queryOrderInfo(Integer uid, Long orderId) throws Exception;
    /**
     * 司机走订单流程
     * @param uid
     * @return
     * @throws Exception
     */
    ResultUtil driverProcessOperations(Integer uid, ProcessOperationsWarpper processOperationsWarpper) throws Exception;
    /**
     * 司机转单操作
     * @param uid
     * @param orderId
     * @param cause
     * @return
     * @throws Exception
     */
    ResultUtil transferOrder(Integer uid, Long orderId, String cause) throws Exception;
    /**
     * 修改终点地址
     * @param uid
     * @param orderEndAddressWarpper
     * @return
     * @throws Exception
     */
    ResultUtil setOrderEndAddress(Integer uid, OrderEndAddressWarpper orderEndAddressWarpper) throws Exception;
    /**
     * 取消转单操作
     * @param uid
     * @param orderId
     * @return
     * @throws Exception
     */
    ResultUtil cancelTransferOrder(Integer uid, Long orderId) throws Exception;
    /**
     * 司机取消订单
     * @param uid
     * @param orderId
     * @param cause
     * @return
     * @throws Exception
     */
    ResultUtil driverCancelOrder(Integer uid, Long orderId, String cause) throws Exception;
    /**
     * 获取订单费用明细
     * @param uid
     * @param orderId
     * @return
     * @throws Exception
     */
    OrderPriceWarpper queryOrderPrice(Integer uid, Long orderId) throws Exception;
    /**
     * 修改订单状态
     * @param uid
     * @param orderId
     * @param state
     * @return
     * @throws Exception
     */
    ResultUtil setOrderStatus(Integer uid, Long orderId, Integer state) throws Exception;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IOrderTransferService.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.driver.modular.system.model.OrderTransfer;
public interface IOrderTransferService extends IService<OrderTransfer> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IRevenueService.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.driver.modular.system.model.Revenue;
public interface IRevenueService extends IService<Revenue> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/IWeatherCityService.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.driver.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.driver.modular.system.model.WeatherCity;
public interface IWeatherCityService extends IService<WeatherCity> {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/CancelOrderServiceImpl.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.driver.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.driver.modular.system.dao.CancelOrderMapper;
import com.supersavedriving.driver.modular.system.model.CancelOrder;
import com.supersavedriving.driver.modular.system.service.ICancelOrderService;
import org.springframework.stereotype.Service;
/**
* 取消订单记录
* @author pzb
* @Date 2023/2/25 14:45
*/
@Service
public class CancelOrderServiceImpl extends ServiceImpl<CancelOrderMapper, CancelOrder> implements ICancelOrderService {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverServiceImpl.java
@@ -150,6 +150,12 @@
        }
        driver.setBranchOfficeId(branchOffice.getId());
        driver.setAgentId(branchOffice.getAgentId());
        driver.setProvinceCode(branchOffice.getProvinceCode());
        driver.setProvinceName(branchOffice.getProvinceName());
        driver.setCityName(branchOffice.getCityName());
        driver.setCityCode(branchOffice.getCityCode());
        driver.setAreaCode(branchOffice.getDistrictCode());
        driver.setAreaName(branchOffice.getDistrictName());
        driver.setInviterType(driverRegisterWarpper.getInviterType());
        driver.setInviterId(driverRegisterWarpper.getInviterId());
        driver.setApprovalStatus(1);
@@ -402,6 +408,12 @@
    }
    /**
     * 获取司机推广二维码
     * @param uid
     * @return
     * @throws Exception
     */
    @Override
    public PromotionWarpper queryPromotionQRCode(Integer uid) throws Exception {
        PromotionWarpper promotionWarpper = new PromotionWarpper();
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/DriverWorkServiceImpl.java
@@ -1,16 +1,15 @@
package com.supersavedriving.driver.modular.system.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.driver.modular.system.dao.DriverWorkMapper;
import com.supersavedriving.driver.modular.system.model.Driver;
import com.supersavedriving.driver.modular.system.model.DriverWork;
import com.supersavedriving.driver.modular.system.model.OrderTransfer;
import com.supersavedriving.driver.modular.system.model.SystemConfig;
import com.supersavedriving.driver.modular.system.service.IDriverService;
import com.supersavedriving.driver.modular.system.service.IDriverWorkService;
import com.supersavedriving.driver.modular.system.service.IOrderService;
import com.supersavedriving.driver.modular.system.service.ISystemConfigService;
import com.supersavedriving.driver.modular.system.service.*;
import com.supersavedriving.driver.modular.system.util.ResultUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -34,6 +33,9 @@
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IOrderTransferService orderTransferService;
@@ -52,8 +54,16 @@
            return ResultUtil.error("账户余额不足,请先充值");
        }
        systemConfig = systemConfigService.selectOne(new EntityWrapper<SystemConfig>().eq("type", 1));
        JSON.parseObject(systemConfig.getContent()).getDouble("num1");
        JSONObject jsonObject = JSON.parseObject(systemConfig.getContent());
        Integer num5 = jsonObject.getInteger("num5");
        OrderTransfer orderTransfer = orderTransferService.selectOne(new EntityWrapper<OrderTransfer>().eq("oldDriverId", driverId)
                .eq("status", 1).isNotNull("successTime").orderBy("createTime desc limit 0, 1"));
        if(null != orderTransfer){
            int i = Double.valueOf((System.currentTimeMillis() - orderTransfer.getSuccessTime().getTime()) / 60000).intValue();
            if(num5 > i){
                return ResultUtil.error("暂时还无法上班,请稍后重试");
            }
        }
        DriverWork driverWork = this.selectOne(new EntityWrapper<DriverWork>().eq("driverId", 1).eq("status", 1));
        if(null != driverWork){
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderPositionServiceImpl.java
@@ -6,20 +6,23 @@
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.driver.core.util.ToolUtil;
import com.supersavedriving.driver.modular.system.model.DriverWork;
import com.supersavedriving.driver.modular.system.model.Order;
import com.supersavedriving.driver.modular.system.service.IDriverWorkService;
import com.supersavedriving.driver.modular.system.service.IOrderPositionService;
import com.supersavedriving.driver.modular.system.service.IOrderService;
import com.supersavedriving.driver.modular.system.util.GeodesyUtil;
import com.supersavedriving.driver.modular.system.util.RedisUtil;
import com.supersavedriving.driver.modular.system.util.ResultUtil;
import com.supersavedriving.driver.modular.system.warpper.DriverPositionWarpper;
import com.supersavedriving.driver.modular.system.warpper.OrderPositionWarpper;
import com.supersavedriving.driver.modular.system.warpper.ProcessOperationsWarpper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.*;
/**
 * 订单轨迹逻辑类
@@ -29,6 +32,14 @@
    @Value("${filePath}")
    private String filePath;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private IOrderService orderService;
    private Map<String, Integer> map = new HashMap<>();
@@ -49,6 +60,10 @@
            file.createNewFile();
        }
        List<OrderPositionWarpper> orderPositionWarppers = queryPosition(orderId, orderType);
        if(orderPositionWarppers.size() > 0){
            OrderPositionWarpper orderPositionWarpper = orderPositionWarppers.get(orderPositionWarppers.size() - 1);
            saveOrderMileage(driverPositionWarpper, orderPositionWarpper);
        }
        OrderPositionWarpper orderPositionWarpper = new OrderPositionWarpper();
        BeanUtils.copyProperties(driverPositionWarpper, orderPositionWarpper);
        orderPositionWarpper.setInsertTime(new Date());
@@ -63,6 +78,49 @@
    /**
     * 保存行驶里程
     * @param driverPositionWarpper
     * @param orderPositionWarpper
     */
    public void saveOrderMileage(DriverPositionWarpper driverPositionWarpper, OrderPositionWarpper orderPositionWarpper){
        String fromLonLat = driverPositionWarpper.getLon() + "," + driverPositionWarpper.getLat();
        String toLonLat = orderPositionWarpper.getLon() + "," + orderPositionWarpper.getLat();
        Map<String, Double> distance = GeodesyUtil.getDistance(fromLonLat, toLonLat);
        Order order = orderService.selectById(driverPositionWarpper.getOrderId());
        Double wgs84 = distance.get("WGS84");
        Integer num = map.get(order.getId().toString());
        if(50 < wgs84){
            order.setActualMileage(order.getActualMileage() + wgs84.intValue());
            map.put(order.getId().toString(), 0);
            if(order.getState() == 401){//定位变动,自动开始服务
                ProcessOperationsWarpper processOperationsWarpper = new ProcessOperationsWarpper();
                processOperationsWarpper.setOrderId(order.getId());
                processOperationsWarpper.setState(105);
                try {
                    orderService.driverProcessOperations(order.getDriverId(), processOperationsWarpper);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        if(50 >= wgs84 && 12 <= (null == num ? 0 : num)){//1分钟(5秒上传一次数据)
            Integer integer = map.get(order.getId().toString());
            map.put(order.getId().toString(), integer++);
            order.setState(401);//进入等待状态
            order.setStartWaitTime(new Date());
        }
        if(50 >= wgs84 && 12 > (null == num ? 0 : num)){
            Integer integer = map.get(order.getId().toString());
            map.put(order.getId().toString(), integer++);
        }
    }
    /**
     * 获取订单坐标数据
     * @param orderId
     * @param orderType
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderServiceImpl.java
@@ -11,11 +11,11 @@
import com.supersavedriving.driver.modular.system.service.*;
import com.supersavedriving.driver.modular.system.util.*;
import com.supersavedriving.driver.modular.system.util.GaoDe.MapUtil;
import com.supersavedriving.driver.modular.system.util.GaoDe.model.District;
import com.supersavedriving.driver.modular.system.util.juhe.WeatherUtil;
import com.supersavedriving.driver.modular.system.util.mongodb.model.Location;
import com.supersavedriving.driver.modular.system.warpper.AddOrderWarpper;
import com.supersavedriving.driver.modular.system.warpper.HallOrderList;
import com.supersavedriving.driver.modular.system.warpper.OrderInfoWarpper;
import com.supersavedriving.driver.modular.system.warpper.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
@@ -71,6 +71,20 @@
    @Autowired
    private IYouTuiDriverService youTuiDriverService;
    @Autowired
    private IWeatherCityService weatherCityService;
    @Autowired
    private IOrderTransferService orderTransferService;
    @Autowired
    private ICancelOrderService cancelOrderService;
    @Autowired
    private IRevenueService revenueService;
    private Map<String, Timer> timerMap = new HashMap<>();
@@ -116,6 +130,7 @@
        if(driverWork != null && null == order1){
            order.setDriverId(uid);
            driver.setServerStatus(2);
            order.setOrderTakingTime(new Date());
        }
        order.setCode(UUIDUtil.getTimeStr() + UUIDUtil.getNumberRandom(3));
        order.setSource(2);
@@ -143,7 +158,13 @@
            d = Double.valueOf(distance.get("distance")) / 1000;
            order.setEstimatedMileage(d);
        }
        order = getOrderPrice(1, d, 0, order, "");
        String city = "";
        District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat());
        if(null != geocode){
            WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getProvince() + "' like district"));
            city = null != weatherCity ? weatherCity.getId().toString() : "";
        }
        order = getOrderPrice(1, d, 0, order, city);
        order.setHallOrder(0);
        order.setState(null == order.getDriverId() ? 101 : 102);
        order.setStatus(1);
@@ -291,9 +312,15 @@
            }
        }
        //计算折扣
        if(null != order.getUserId()){
        }
        //计算总金额
        BigDecimal bigDecimal = new BigDecimal(order.getStartPrice() + order.getOverDrivePrice() + order.getLongDistancePrice() + order.getOverLongDistancePrice() +
                order.getWaitTimePrice() + order.getOutWaitTimePrice() + order.getBadWeatherPrice() + order.getOverBadWeatherPrice()).setScale(2, BigDecimal.ROUND_HALF_EVEN);
                order.getWaitTimePrice() + order.getOutWaitTimePrice() + order.getBadWeatherPrice() + order.getOverBadWeatherPrice() - order.getDiscountAmount()).setScale(2, BigDecimal.ROUND_HALF_EVEN);
        if(type == 1){//预估价
            order.setEstimatedPrice(bigDecimal.doubleValue());
        }
@@ -328,6 +355,8 @@
        order.setOverBadWeatherPrice(0D);//恶劣天气超出里程费
        order.setDiscountedPrice(0D);//优惠金额
        order.setCouponId(null);//优惠券
        order.setDiscountAmount(0D);//折扣优惠金额
        order.setDiscount(0D);//折扣
        return order;
    }
@@ -446,7 +475,7 @@
                @Override
                public void run() {
                    Order order1 = OrderServiceImpl.this.selectById(order.getId());
                    if(order1.getState() == 101){
                    if(order1.getState() == 101 || order1.getState() == 201){
                        order1.setHallOrder(1);
                        OrderServiceImpl.this.updateById(order1);
                    }
@@ -535,11 +564,13 @@
                }
            }
            Order order = this.selectById(orderId);
            if(order.getState() != 301){
            Integer state = order.getState();
            Integer oldDriverId = order.getDriverId();
            if(state != 301){
                redisUtil.unlock();
                return ResultUtil.error("订单已被取消");
            }
            if(order.getState() != 101){
            if(state != 101){
                redisUtil.unlock();
                return ResultUtil.error("手速慢了哦");
            }
@@ -547,11 +578,49 @@
            order.setAgentId(driver.getAgentId());
            order.setBranchOfficeId(driver.getBranchOfficeId());
            order.setState(102);
            order.setOrderTakingTime(new Date());
            this.updateById(order);
            redisUtil.unlock();
            driver.setServerStatus(2);
            driverService.updateById(driver);
            if(state == 201){//转单的订单
                //停止定时任务
                Timer timer = timerMap.get(order.getId().toString());
                if(null != timer){
                    timer.cancel();
                    timerMap.remove(order.getId().toString());
                }
                //原司机下班
                Driver oldDriver = driverService.selectById(oldDriverId);
                oldDriver.setServerStatus(1);
                driverService.updateById(oldDriver);
                DriverWork driverWork1 = driverWorkService.selectOne(new EntityWrapper<DriverWork>().eq("driverId", oldDriverId).eq("status", 1));
                driverWork1.setStatus(2);
                driverWork1.setOffWorkTime(new Date());
                driverWorkService.updateById(driverWork1);
                //添加关系数据
                OrderTransfer orderTransfer = orderTransferService.selectOne(new EntityWrapper<OrderTransfer>().eq("orderId", order.getId()).eq("status", 1).isNull("successTime"));
                if(null != orderTransfer){
                    orderTransfer.setNewDriverId(uid);
                    orderTransfer.setSuccessTime(new Date());
                    orderTransferService.updateById(orderTransfer);
                }else{
                    orderTransfer = new OrderTransfer();
                    orderTransfer.setOrderId(order.getId());
                    orderTransfer.setOldDriverId(oldDriverId);
                    orderTransfer.setCreateTime(new Date());
                    orderTransfer.setStatus(1);
                    orderTransfer.setNewDriverId(uid);
                    orderTransfer.setSuccessTime(new Date());
                    orderTransferService.insert(orderTransfer);
                }
                pushUtil.pushTransferSuccessful(order.getUserId(), 1, order.getId());
                pushUtil.pushTransferSuccessful(oldDriverId, 2, order.getId());
            }
            //推动订单数据
            new Thread(new Runnable() {
@@ -590,4 +659,314 @@
        orderInfoWarpper.setCurrentDistance(wgs84);
        return orderInfoWarpper;
    }
    /**
     * 司机走订单流程
     * @param uid
     * @param processOperationsWarpper
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil driverProcessOperations(Integer uid, ProcessOperationsWarpper processOperationsWarpper) throws Exception {
        //101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待支付,108=待评价,109=已完成,201=转单中,301=已取消,401=等待中
        Order order = this.selectById(processOperationsWarpper.getOrderId());
        if(order.getState() == processOperationsWarpper.getState()){
            return ResultUtil.error("不能重复操作");
        }
        if(order.getState() == 201){
            return ResultUtil.error("订单正在转单中");
        }
        order.setState(processOperationsWarpper.getState());
        switch (processOperationsWarpper.getState()){
            case 103:
                order.setGoToAppointmentPointTime(new Date());
                pushOrderInfo(order.getId(), uid);//开始推送订单数据
                break;
            case 104:
                order.setStartWaitTime(new Date());
                order.setArrivalTimeAtTheAppointmentPoint(new Date());
                break;
            case 105:
                if(null == order.getStartTime()){
                    redisUtil.addSetValue("serverOrder", order.getId().toString());//存入缓存用于计算实时距离
                    order.setBoardingTime(new Date());
                    order.setStartTime(new Date());
                }
                order.setStartWaitTime(null);
                //计算等待用户时长
                Integer w = Double.valueOf((System.currentTimeMillis() - order.getStartWaitTime().getTime()) / 60000).intValue();
                order.setWaitTime(order.getWaitTime() + w);
                break;
            case 106:
                order.setGetoffTime(new Date());
                if(ToolUtil.isEmpty(order.getEndAddress())){
                    order.setEndAddress(processOperationsWarpper.getEndAddress());
                    order.setEndLng(processOperationsWarpper.getEndLng());
                    order.setEndLat(processOperationsWarpper.getEndLat());
                }
                //停止定时任务
                Timer timer = timerMap.get(order.getId().toString());
                if(null != timer){
                    timer.cancel();
                    timerMap.remove(order.getId().toString());
                }
                //开始计算费用
                String city = "";
                District geocode = MapUtil.geocode(order.getEndLng(), order.getEndLat());
                if(null != geocode){
                    WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getProvince() + "' like district"));
                    city = null != weatherCity ? weatherCity.getId().toString() : "";
                }
                order = getOrderPrice(2, Double.valueOf(order.getActualMileage() / 1000), order.getWaitTime(), order, city);
                //修改司机状态
                Driver driver = driverService.selectById(order.getDriverId());
                driver.setServerStatus(1);
                driverService.updateById(driver);
                break;
            case 401:
                order.setStartWaitTime(new Date());
                break;
        }
        this.updateAllColumnById(order);
        //推送订单状态
        pushUtil.pushOrderStatus(order.getDriverId(), 2, order.getId(), order.getState());
        if(null != order.getUserId()){
            pushUtil.pushOrderStatus(order.getUserId(), 1, order.getId(), order.getState());
        }
        return ResultUtil.success();
    }
    /**
     * 定时任务推送订单数据
     * @param orderId
     * @param uid
     */
    public void pushOrderInfo(Long orderId, Integer uid){
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                String value = redisUtil.getValue("DRIVER" + uid);
                Order order = OrderServiceImpl.this.selectById(orderId);
                if(order.getState() == 106){
                    Timer timer = timerMap.get(order.getId().toString());
                    if(null != timer){
                        timer.cancel();
                        timerMap.remove(order.getId().toString());
                    }
                }
                PushOrderInfoWarpper pushOrderInfoWarpper = new PushOrderInfoWarpper();
                pushOrderInfoWarpper.setId(orderId);
                if(ToolUtil.isNotEmpty(value)){
                    String[] split = value.split(",");
                    pushOrderInfoWarpper.setDriverLat(split[1]);
                    pushOrderInfoWarpper.setDriverLng(split[0]);
                }
                pushOrderInfoWarpper.setWaitTime(order.getWaitTime());
                pushOrderInfoWarpper.setState(order.getState());
                pushOrderInfoWarpper.setActualMileage(Double.valueOf(order.getActualMileage() / 1000));
                int travelTime = Double.valueOf((System.currentTimeMillis() - order.getStartTime().getTime()) / 60000).intValue();
                pushOrderInfoWarpper.setTravelTime(travelTime);
                pushUtil.pushOrderInfo(uid, 2, pushOrderInfoWarpper);
            }
        },0, 5000);
        timerMap.put(orderId.toString(), timer);
    }
    /**
     * 司机转单操作
     * @param uid
     * @param orderId
     * @param cause
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil transferOrder(Integer uid, Long orderId, String cause) throws Exception {
        Order order = this.selectById(orderId);
        if(order.getDriverId().compareTo(uid) != 0){
            return ResultUtil.error("无权操作");
        }
        if(order.getState() > 104){
            return ResultUtil.error("订单不支持转单");
        }
        order.setOldState(order.getState());
        order.setState(201);
        this.updateById(order);
        OrderTransfer orderTransfer = new OrderTransfer();
        orderTransfer.setOrderId(orderId);
        orderTransfer.setOldDriverId(order.getDriverId());
        orderTransfer.setCause(cause);
        orderTransfer.setStatus(1);
        orderTransfer.setCreateTime(new Date());
        orderTransferService.insert(orderTransfer);
        //开始派单
        pushOrder(order);
        return ResultUtil.success();
    }
    /**
     * 司机修改订单终点
     * @param uid
     * @param orderEndAddressWarpper
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil setOrderEndAddress(Integer uid, OrderEndAddressWarpper orderEndAddressWarpper) throws Exception {
        Order order = this.selectById(orderEndAddressWarpper.getOrderId());
        order.setEndLat(orderEndAddressWarpper.getEndLat());
        order.setEndLng(orderEndAddressWarpper.getEndLng());
        order.setEndAddress(orderEndAddressWarpper.getEndAddress());
        Map<String, String> distance = MapUtil.getDistance(order.getStartLng() + "," + order.getStartLat(), order.getEndLng() + "," + order.getEndLat(), 1);
        if(null == distance){
            return ResultUtil.error("获取预估距离出错");
        }
        Double d = Double.valueOf(distance.get("distance")) / 1000;
        order.setEstimatedMileage(d);
        String city = "";
        District geocode = MapUtil.geocode(order.getStartLng(), order.getStartLat());
        if(null != geocode){
            WeatherCity weatherCity = weatherCityService.selectOne(new EntityWrapper<WeatherCity>().where(" '" + geocode.getProvince() + "' like district"));
            city = null != weatherCity ? weatherCity.getId().toString() : "";
        }
        order = getOrderPrice(1, d, 0, order, city);
        this.updateById(order);
        return ResultUtil.success();
    }
    /**
     * 司机取消转到操作
     * @param uid
     * @param orderId
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil cancelTransferOrder(Integer uid, Long orderId) throws Exception {
        Order order = this.selectById(orderId);
        if(order.getState() != 201){
            return ResultUtil.error("不能取消转单");
        }
        order.setState(order.getOldState());
        order.setOldState(null);
        this.updateAllColumnById(order);
        OrderTransfer orderTransfer = orderTransferService.selectOne(new EntityWrapper<OrderTransfer>().eq("orderId", orderId)
                .eq("status", 1).isNull("successTime").orderBy("createTime desc limit 0, 1"));
        if(null != orderTransfer){
            orderTransfer.setStatus(3);
            orderTransferService.updateById(orderTransfer);
        }
        return ResultUtil.success();
    }
    /**
     * 司机取消订单
     * @param uid
     * @param orderId
     * @param cause
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil driverCancelOrder(Integer uid, Long orderId, String cause) throws Exception {
        Order order = this.selectById(orderId);
        if(uid.compareTo(order.getDriverId()) != 0){
            return ResultUtil.error("无法取消订单");
        }
        if(order.getState() > 105){
            return ResultUtil.error("无法取消订单");
        }
        order.setState(301);
        this.updateById(order);
        CancelOrder cancelOrder = new CancelOrder();
        cancelOrder.setOrderId(orderId);
        cancelOrder.setUserType(2);
        cancelOrder.setUserId(uid);
        cancelOrder.setCause(cause);
        cancelOrder.setStatus(1);
        cancelOrder.setCreateTime(new Date());
        cancelOrderService.insert(cancelOrder);
        return ResultUtil.success();
    }
    /**
     * 获取订单费用明细
     * @param uid
     * @param orderId
     * @return
     * @throws Exception
     */
    @Override
    public OrderPriceWarpper queryOrderPrice(Integer uid, Long orderId) throws Exception {
        Driver driver = driverService.selectById(uid);
        Order order = this.selectById(orderId);
        OrderPriceWarpper orderPriceWarpper = new OrderPriceWarpper();
        BeanUtils.copyProperties(order, orderPriceWarpper);
        orderPriceWarpper.setActualMileage(new BigDecimal(order.getActualMileage() / 1000).setScale(2, BigDecimal.ROUND_HALF_EVEN).doubleValue());
        orderPriceWarpper.setTravelTime(Double.valueOf((order.getGetoffTime().getTime() - order.getStartTime().getTime()) / 60000).intValue());
        orderPriceWarpper.setWxCollectionCode(driver.getWxCollectionCode());
        orderPriceWarpper.setZfbCollectionCode(driver.getZfbCollectionCode());
        return orderPriceWarpper;
    }
    /**
     * 修改订单状态
     * @param uid
     * @param orderId
     * @param state
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil setOrderStatus(Integer uid, Long orderId, Integer state) throws Exception {
        List<Integer> s = Arrays.asList(107, 108);
        if(s.contains(state)){
            return ResultUtil.error("操作失败");
        }
        Order order = this.selectById(orderId);
        order.setState(state);
        if(state == 108){
            order.setPayType(3);
            order.setPayTime(new Date());
            order.setPayMoney(order.getOrderMoney() - order.getDiscountAmount());
        }
        this.updateById(order);
        if(state == 108){//计算抽成
            saveRevenue(order);
        }
        pushUtil.pushOrderStatus(order.getDriverId(), 2, orderId, order.getState());
        if(null != order.getUserId()){
            pushUtil.pushOrderStatus(order.getUserId(), 1, orderId, order.getState());
        }
        return ResultUtil.success();
    }
    /**
     * 计算抽成和分佣
     * @param order
     */
    public void saveRevenue(Order order){
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/OrderTransferServiceImpl.java
New file
@@ -0,0 +1,11 @@
package com.supersavedriving.driver.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.driver.modular.system.dao.OrderTransferMapper;
import com.supersavedriving.driver.modular.system.model.OrderTransfer;
import com.supersavedriving.driver.modular.system.service.IOrderTransferService;
import org.springframework.stereotype.Service;
@Service
public class OrderTransferServiceImpl extends ServiceImpl<OrderTransferMapper, OrderTransfer> implements IOrderTransferService {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/RevenueServiceImpl.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.driver.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.driver.modular.system.dao.RevenueMapper;
import com.supersavedriving.driver.modular.system.model.Revenue;
import com.supersavedriving.driver.modular.system.service.IRevenueService;
import org.springframework.stereotype.Service;
/**
* 收入记录
* @author pzb
* @Date 2023/2/25 16:12
*/
@Service
public class RevenueServiceImpl extends ServiceImpl<RevenueMapper, Revenue> implements IRevenueService {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/service/impl/WeatherCityServiceImpl.java
New file
@@ -0,0 +1,11 @@
package com.supersavedriving.driver.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.driver.modular.system.dao.WeatherCityMapper;
import com.supersavedriving.driver.modular.system.model.WeatherCity;
import com.supersavedriving.driver.modular.system.service.IWeatherCityService;
import org.springframework.stereotype.Service;
@Service
public class WeatherCityServiceImpl extends ServiceImpl<WeatherCityMapper, WeatherCity> implements IWeatherCityService {
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/ALiApiUtil.java
@@ -3,6 +3,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -14,9 +15,6 @@
 */
@Component
public class ALiApiUtil {
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
@@ -34,7 +32,12 @@
        param.put("verifyKey", "IVO4js5kValcdt");
        param.put("userName", name);
        param.put("identifyNum", code);
        String get = httpClientUtil.pushHttpRequset("GET", url, param, header, "form");
        String get = null;
        try {
            get = HttpClientUtil.pushHttpRequset("GET", url, param, header, "form").getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = JSON.parseObject(get);
        if(jsonObject.getIntValue("code") == 200){
            JSONObject value = jsonObject.getJSONObject("value");
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/ChinaMobileUtil.java
@@ -2,6 +2,8 @@
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.driver.core.util.MD5Util;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpResult;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -18,9 +20,6 @@
    private String APIKey = "zj42494b1bdd416b9762229af6b5cbbd";
    private String SecretKey = "30323561316534653735613230316339";
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
@@ -52,7 +51,8 @@
        Map<String, String> header = new HashMap<String, String>(3);
        header.put("Authorization", "Basic " + new String(Base64.encodeBase64((APIKey + ":" + SecretKey).getBytes())));
        header.put("Content-Type", "application/json;charset=utf-8");
        String post = httpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/binding", request, header, "json");
        HttpResult httpResult = HttpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/binding", request, header, "json");
        String post = httpResult.getData();
        Map<String, String> map1 = new HashMap<>();
        if(post.indexOf("0000") != -1){
            JSONObject jsonObject = JSONObject.parseObject(post);
@@ -90,7 +90,8 @@
        Map<String, String> header = new HashMap<String, String>(3);
        header.put("Authorization", "Basic " + new String(Base64.encodeBase64((APIKey + ":" + SecretKey).getBytes())));
        header.put("Content-Type", "application/json;charset=utf-8");
        String post = httpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/unbinding", request, header, "json");
        HttpResult httpResult = HttpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/unbinding", request, header, "json");
        String post = httpResult.getData();
        JSONObject jsonObject = JSONObject.parseObject(post);
        Map<String, String> map1 = new HashMap<>();
        if(jsonObject.getString("code").equals("0000")){
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/GaoDe/MapUtil.java
@@ -3,13 +3,18 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.driver.modular.system.util.GaoDe.model.District;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.supersavedriving.driver.modular.system.util.GaoDe.MapConfig.key;
/**
* 地图工具类
@@ -32,7 +37,7 @@
     */
    public static Map<String, String> getDistance(String origins, String destination, Integer type){
        try {
            String url = "https://restapi.amap.com/v3/distance?key=" + MapConfig.key + "&origins=" + origins + "&destination=" + destination +
            String url = "https://restapi.amap.com/v3/distance?key=" + key + "&origins=" + origins + "&destination=" + destination +
                    "&type=" + type;
            HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json");
            if(httpResult.getCode() != 200){
@@ -57,4 +62,78 @@
        }
        return null;
    }
    /**
     * 地址转换经纬度
     * @param address
     * @return
     */
    public static List<String> geocoding(String address){
        try {
            String url = "https://restapi.amap.com/v3/geocode/geo?key=" + key + "&output=JSON&address=" + address;
            HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json");
            if(httpResult.getCode() != 200){
                return null;
            }
            JSONObject jsonObject = JSON.parseObject(httpResult.getData());
            String status = jsonObject.getString("status");
            List<String> list = new ArrayList<>();
            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);
                }
            }
            return list;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
    /**
     * 根据经纬度获取行政区域信息
     * @param lon
     * @param lan
     * @return
     * @throws Exception
     */
    public static District geocode(String lon, String lan) {
        try {
            String url = "https://restapi.amap.com/v3/geocode/regeo?key=" + key + "&location=" + lon + "," + lan;
            HttpResult httpResult = HttpClientUtil.pushHttpRequset("GET", url, null, null, "json");
            if(httpResult.getCode() != 200){
                return null;
            }
            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");
                District district1 = new District();
                district1.setProvince(province);
                district1.setProvinceCode(code.substring(0, 2) + "0000");
                district1.setCity(city);
                district1.setCityCode(code.substring(0, 4) + "00");
                district1.setDistrict(district);
                district1.setDistrictCode(code);
                return district1;
            }
            logger.debug(httpResult.getData());
            return null;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/GaoDe/model/District.java
New file
@@ -0,0 +1,37 @@
package com.supersavedriving.driver.modular.system.util.GaoDe.model;
import com.baomidou.mybatisplus.annotations.TableField;
import lombok.Data;
/**
* 行政区域
* @author pzb
* @Date 2023/2/25 11:40
*/
@Data
public class District {
    /**
     * 省名称
     */
    private String province;
    /**
     * 省编号
     */
    private String provinceCode;
    /**
     * 市名称
     */
    private String city;
    /**
     * 市编号
     */
    private String cityCode;
    /**
     * 区县名称
     */
    private String district;
    /**
     * 区县编号
     */
    private String districtCode;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/JuHeUtil.java
File was deleted
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/PayMoneyUtil.java
@@ -15,6 +15,7 @@
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.supersavedriving.driver.modular.system.util.httpClinet.HttpClientUtil;
import org.apache.commons.collections.map.HashedMap;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.dom4j.Document;
@@ -72,9 +73,6 @@
    @Value("${callbackPath}")
    private String callbackPath;//支付回调网关地址
    @Autowired
    private HttpClientUtil httpClientUtil;
    private Map<String, JSONObject> order = new HashMap<>();//存储支付订单用于主动查询支付结果
@@ -260,7 +258,7 @@
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        String body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData();
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
@@ -404,7 +402,12 @@
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        String body1 = null;
        try {
            body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
@@ -506,7 +509,12 @@
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        String body1 = null;
        try {
            body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData();
        } catch (Exception e) {
            e.printStackTrace();
        }
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
@@ -647,7 +655,7 @@
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        String body1 = HttpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>()).getData();
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/PushUtil.java
@@ -2,6 +2,7 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.driver.modular.system.warpper.PushOrderInfoWarpper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -164,4 +165,70 @@
            System.err.println(jsonObject1.getString("msg"));
        }
    }
    /**
     * 推送订单数据
     * @param id
     * @param type
     * @param pushOrderInfoWarpper
     */
    public void pushOrderInfo(Integer id, Integer type, PushOrderInfoWarpper pushOrderInfoWarpper){
        JSONObject msg = new JSONObject();
        msg.put("code", 200);
        msg.put("msg", "SUCCESS");
        msg.put("method", "ORDER_INFO");
        msg.put("data", pushOrderInfoWarpper);
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("msg", msg.toJSONString());
        params.add("id", id.toString());
        params.add("type", type.toString());
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = internalRestTemplate.postForObject("http://zuul-gateway/netty/sendMsgToClient",requestEntity , String.class);
        JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
        if(jsonObject1.getIntValue("code") != 200){
            logger.debug(jsonObject1.getString("msg"));
            System.err.println(jsonObject1.getString("msg"));
        }
    }
    /**
     * 转单成功推送
     * @param id
     * @param type
     */
    public void pushTransferSuccessful(Integer id, Integer type, Long orderId){
        JSONObject msg = new JSONObject();
        msg.put("code", 200);
        msg.put("msg", "SUCCESS");
        msg.put("method", "TRANSFER_SUCCESS");
        Map<String, Object> map = new HashMap<>();
        map.put("orderId", orderId);
        msg.put("data", map);
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("msg", msg.toJSONString());
        params.add("id", id.toString());
        params.add("type", type.toString());
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = internalRestTemplate.postForObject("http://zuul-gateway/netty/sendMsgToClient",requestEntity , String.class);
        JSONObject jsonObject1 = JSON.parseObject(s, JSONObject.class);
        if(jsonObject1.getIntValue("code") != 200){
            logger.debug(jsonObject1.getString("msg"));
            System.err.println(jsonObject1.getString("msg"));
        }
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/httpClinet/HttpClientUtil.java
@@ -168,7 +168,7 @@
     * @param header    自定义请求头
     * @return
     */
    public HttpResult pushHttpRequsetXml(String url, String xml, Map<String, String> header) throws Exception{
    public static 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()){
@@ -180,7 +180,7 @@
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        String content = EntityUtils.toString(httpResponse.getEntity(), "UTF-8");
        HttpResult httpResult = HttpResult.getHttpResult(statusCode, content);
        this.close(httpResponse);
        close(httpResponse);
        return httpResult;
    }
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherCityInfo.java
New file
@@ -0,0 +1,38 @@
package com.supersavedriving.driver.modular.system.util.juhe;
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 pzb
* @Date 2023/2/25 10:56
*/
@Data
@TableName("t_weather_city")
public class WeatherCityInfo {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.INPUT)
    @TableField("id")
    private Integer id;
    /**
     * 省
     */
    @TableField("province")
    private String province;
    /**
     * 市
     */
    @TableField("city")
    private String city;
    /**
     * 区
     */
    @TableField("district")
    private String district;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherRes.java
File was deleted
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/util/juhe/WeatherUtil.java
@@ -9,6 +9,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.List;
/**
* 天气工具类
@@ -84,4 +86,34 @@
        }
        return false;
    }
    /**
     * 获取支持城市列表
     * @return
     */
    public static List<WeatherCityInfo> queryCityList(){
        String url = "http://apis.juhe.cn/simpleWeather/cityList?key=" + key;
        HttpResult httpResult = null;
        try {
            httpResult = httpClientUtil.pushHttpRequset("GET", url, null, null, "json");
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(httpResult.getCode() != 200){
            logger.debug("查询支持城市失败:" + httpResult.getData());
            return null;
        }
        String data = httpResult.getData();
        JSONObject jsonObject = JSON.parseObject(data);
        Integer error_code = jsonObject.getInteger("error_code");
        if(0 != error_code){
            logger.debug("查询支持城失败:" + jsonObject.getString("reason"));
            return null;
        }
        JSONArray result = jsonObject.getJSONArray("result");
        List<WeatherCityInfo> weatherCities = result.toJavaList(WeatherCityInfo.class);
        return weatherCities;
    }
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderEndAddressWarpper.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.driver.modular.system.warpper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class OrderEndAddressWarpper {
    @ApiModelProperty(value = "订单id", dataType = "long", required = true)
    private Long orderId;
    @ApiModelProperty(value = "终点地址(106上传)", dataType = "string", required = true)
    private String endAddress;
    @ApiModelProperty(value = "终点纬度(106上传)", dataType = "string", required = true)
    private String endLat;
    @ApiModelProperty(value = "终点经度(106上传)", dataType = "string", required = true)
    private String endLng;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderInfoWarpper.java
@@ -47,6 +47,6 @@
    private Double actualMileage;
    @ApiModelProperty("行驶时间")
    private Integer travelTime;
    @ApiModelProperty("订单状态(101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待评价,108=已完成,201=转单中,301=已取消)")
    @ApiModelProperty("订单状态(101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待支付,108=待评价,109=已完成,201=转单中,301=已取消,401=等待中)")
    private Integer state;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/OrderPriceWarpper.java
New file
@@ -0,0 +1,59 @@
package com.supersavedriving.driver.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
/**
* 订单金额
* @author pzb
* @Date 2023/2/25 15:11
*/
@Data
@ApiModel
public class OrderPriceWarpper {
    @ApiModelProperty("订单金额")
    private Double orderMoney;
    @ApiModelProperty("总行驶里程")
    private Double actualMileage;
    @ApiModelProperty("总行驶时间")
    private Integer travelTime;
    @ApiModelProperty("起步里程")
    private Double startDistance;
    @ApiModelProperty("起步价")
    private Double startPrice;
    @ApiModelProperty("超过起步里程")
    private Double overDriveDistance;
    @ApiModelProperty("超过起步里程费")
    private Double overDrivePrice;
    @ApiModelProperty("长途里程")
    private Double longDistance;
    @ApiModelProperty("长途费")
    private Double longDistancePrice;
    @ApiModelProperty("超过长途里程")
    private Double overLongDistance;
    @ApiModelProperty("超过长途里程费")
    private Double overLongDistancePrice;
    @ApiModelProperty("等待时长")
    private Integer waitTime;
    @ApiModelProperty("等待费")
    private Double waitTimePrice;
    @ApiModelProperty("超出等待时长")
    private Integer outWaitTime;
    @ApiModelProperty("超出等待费")
    private Double outWaitTimePrice;
    @ApiModelProperty("恶劣天气里程")
    private Double badWeatherDistance;
    @ApiModelProperty("恶劣天气费")
    private Double badWeatherPrice;
    @ApiModelProperty("恶劣天气超出里程")
    private Double overBadWeatherDistance;
    @ApiModelProperty("恶劣天气超出里程费")
    private Double overBadWeatherPrice;
    @ApiModelProperty("折扣金额")
    private Double discountAmount;
    @ApiModelProperty("微信收款码")
    private String wxCollectionCode;
    @ApiModelProperty("支付宝收款码")
    private String zfbCollectionCode;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/ProcessOperationsWarpper.java
New file
@@ -0,0 +1,18 @@
package com.supersavedriving.driver.modular.system.warpper;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class ProcessOperationsWarpper {
    @ApiModelProperty(value = "订单id", dataType = "long", required = true)
    private Long orderId;
    @ApiModelProperty(value = "状态码(103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,401=等待中)", dataType = "int", required = true)
    private Integer state;
    @ApiModelProperty(value = "终点地址(106上传)", dataType = "string", required = false)
    private String endAddress;
    @ApiModelProperty(value = "终点纬度(106上传)", dataType = "string", required = false)
    private String endLat;
    @ApiModelProperty(value = "终点经度(106上传)", dataType = "string", required = false)
    private String endLng;
}
driver/guns-admin/src/main/java/com/supersavedriving/driver/modular/system/warpper/PushOrderInfoWarpper.java
New file
@@ -0,0 +1,24 @@
package com.supersavedriving.driver.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
@ApiModel
public class PushOrderInfoWarpper {
    @ApiModelProperty("订单id")
    private Long id;
    @ApiModelProperty("司机纬度")
    private String driverLat;
    @ApiModelProperty("司机经度")
    private String driverLng;
    @ApiModelProperty("等待时长(分钟)")
    private Integer waitTime;
    @ApiModelProperty("行驶里程(公里)")
    private Double actualMileage;
    @ApiModelProperty("行驶时间(分钟)")
    private Integer travelTime;
    @ApiModelProperty("101=待接单,102=已接单,103=前往预约点,104=到达预约点,105=开始服务,106=到达目的地,107=待支付,108=待评价,109=已完成,201=转单中,301=已取消,401=等待中")
    private Integer state;
}
driver/guns-admin/src/main/resources/application.yml
@@ -121,4 +121,4 @@
spring:
  data:
    mongodb:
      uri: mongodb://admin:123456@127.0.0.1:27017/admin
      uri: mongodb://127.0.0.1:27017/admin
driver/guns-admin/src/main/resources/logback-spring.xml
@@ -187,7 +187,7 @@
    <!-- 4  最终的策略:
                 基本策略(root级) + 根据profile在启动时, logger标签中定制化package日志级别(优先级高于上面的root级)-->
    <springProfile name="dev">
        <root level="debug">
        <root level="info">
            <appender-ref ref="CONSOLE" />
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
driver/guns-admin/src/test/java/com.supersavedriving.driver/GunsApplicationTest.java
New file
@@ -0,0 +1,36 @@
//package com.supersavedriving.driver;
//
//import com.supersavedriving.driver.modular.system.model.WeatherCity;
//import com.supersavedriving.driver.modular.system.service.IWeatherCityService;
//import com.supersavedriving.driver.modular.system.util.juhe.WeatherCityInfo;
//import com.supersavedriving.driver.modular.system.util.juhe.WeatherUtil;
//import org.junit.Test;
//import org.junit.runner.RunWith;
//import org.springframework.beans.BeanUtils;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.boot.test.context.SpringBootTest;
//import org.springframework.test.context.junit4.SpringRunner;
//
//import java.util.ArrayList;
//import java.util.List;
//
//@RunWith(SpringRunner.class)
//@SpringBootTest
//public class GunsApplicationTest {
//
//    @Autowired
//    private IWeatherCityService weatherCityService;
//
//
//    @Test
//    public void test(){
//        List<WeatherCityInfo> weatherCities = WeatherUtil.queryCityList();
//        List<WeatherCity> list = new ArrayList<>();
//        for (WeatherCityInfo weatherCityInfo : weatherCities) {
//            WeatherCity weatherCity1 = new WeatherCity();
//            BeanUtils.copyProperties(weatherCityInfo, weatherCity1);
//            list.add(weatherCity1);
//        }
//        weatherCityService.insertBatch(list);
//    }
//}
super_save_driving.sql
Diff too large
user/guns-admin/pom.xml
New file
@@ -0,0 +1,261 @@
<?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>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--整合hystrix-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <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>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.11.3</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </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>
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </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>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>cn.jpush.api</groupId>
            <artifactId>jpush-client</artifactId>
            <version>3.3.10</version>
        </dependency>
        <dependency>
            <groupId>dom4j</groupId>
            <artifactId>dom4j</artifactId>
            <version>1.6.1</version>
        </dependency>
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.8.10.ALL</version>
        </dependency>
        <!-- oos对象存储 -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.8.0</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core -->
        <dependency>
            <groupId>com.aliyun</groupId>
            <artifactId>aliyun-java-sdk-core</artifactId>
            <version>4.4.3</version>
        </dependency>
        <!-- 计算两坐标间的直线距离 -->
        <dependency>
            <groupId>org.gavaghan</groupId>
            <artifactId>geodesy</artifactId>
            <version>1.1.3</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.13</version>
        </dependency>
    </dependencies>
    <build>
        <!--打包jar包方式-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork><!-- 如果没有该项配置,肯呢个devtools不会起作用,即应用不会restart -->
                </configuration>
            </plugin>
        </plugins>
        <!--打包war包引入本地jar的打包方式-->
        <!--<plugins>-->
            <!--<plugin>-->
                <!--<groupId>org.apache.maven.plugins</groupId>-->
                <!--<artifactId>maven-war-plugin</artifactId>-->
                <!--<configuration>-->
                    <!--&lt;!&ndash; 设置成false,否则检查web.xml是否存在。因为springboot是没有web.xml的 &ndash;&gt;-->
                    <!--<failOnMissingWebXml>false</failOnMissingWebXml>-->
                    <!--&lt;!&ndash;打包后的项目名&ndash;&gt;-->
                    <!--&lt;!&ndash;<warName>example</warName>&ndash;&gt;-->
                    <!--<webResources>-->
                        <!--<resource>-->
                            <!--&lt;!&ndash;把本地lib里面的jar复制到lib&ndash;&gt;-->
                            <!--<directory>${project.basedir}/lib</directory>-->
                            <!--<targetPath>WEB-INF/lib/</targetPath>-->
                            <!--<includes>-->
                                <!--<include>**/*.jar</include>-->
                            <!--</includes>-->
                        <!--</resource>-->
                    <!--</webResources>-->
                <!--</configuration>-->
            <!--</plugin>-->
        <!--</plugins>-->
        <resources>
            <resource>
                <directory>lib</directory>
                <targetPath>/BOOT-INF/lib/</targetPath>
                <includes>
                    <include>**/*.jar</include>
                </includes>
            </resource>
            <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>
        </resources>
    </build>
</project>
user/guns-admin/src/main/java/com/supersavedriving/user/GunsApplication.java
New file
@@ -0,0 +1,86 @@
package com.supersavedriving.user;
import com.supersavedriving.user.modular.system.util.GDFalconUtil;
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.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
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
 */
@EnableEurekaClient//注册为服务提供者
@SpringBootApplication
@EnableScheduling//开启定时任务
@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!");
        GDFalconUtil gdFalconUtil = new GDFalconUtil();
        gdFalconUtil.init();//初始化猎鹰服务
    }
    @Bean //SpringCloud内部服务质检使用服务名调用
    @LoadBalanced
    public RestTemplate internalRestTemplate() {
        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(30 * 3000);
        httpRequestFactory.setReadTimeout(30 * 3000);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
    /**
     * 向Spring容器中定义RestTemplate对象
     * @return
     */
    @Bean //必须new 一个RestTemplate并放入spring容器当中,否则启动时报错
    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(30 * 3000);
        httpRequestFactory.setReadTimeout(30 * 3000);
        RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/GunsServletInitializer.java
New file
@@ -0,0 +1,18 @@
package com.supersavedriving.user;
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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/EhCacheConfig.java
New file
@@ -0,0 +1,39 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/RedisConfig.java
New file
@@ -0,0 +1,46 @@
package com.supersavedriving.user.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
@PropertySource("classpath:redis.properties")
public class RedisConfig {
    @Value("${spring.redis.host}")
    private String host;
    @Value("${spring.redis.port}")
    private int port;
    @Value("${spring.redis.timeout}")
    private int timeout;
    @Value("${spring.redis.jedis.pool.max-idle}")
    private int maxIdle;
    @Value("${spring.redis.jedis.pool.max-wait}")
    private long maxWaitMillis;
    @Value("${spring.redis.password}")
    private String password;
    @Value("${spring.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/SpringSessionConfig.java
New file
@@ -0,0 +1,15 @@
package com.supersavedriving.user.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 {
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/SwaggerConfig.java
New file
@@ -0,0 +1,47 @@
package com.supersavedriving.user.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.supersavedriving.user.modular.system.controller"))    //这里采用包扫描的方式来确定要显示的接口
                .paths(PathSelectors.any())
                .build();
    }
    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("OK出行 Doc")
                .description("所有接口前需要加 /driver 前缀,例如:/driver/base/agreement/queryByType <br>所有以 /api/*** 路径的接口需要上传签名参数sign")
//                .termsOfServiceUrl("http://git.oschina.net/naan1993/guns")
                .contact("stylefeng")
                .version("1.0")
                .build();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/datasource/MultiDataSourceConfig.java
New file
@@ -0,0 +1,125 @@
package com.supersavedriving.user.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.supersavedriving.user.core.config.properties.DruidProperties;
import com.supersavedriving.user.core.config.properties.MutiDataSourceProperties;
import com.supersavedriving.user.core.datascope.DataScopeInterceptor;
import com.supersavedriving.user.core.mutidatasource.DynamicDataSource;
import com.supersavedriving.user.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.supersavedriving.user.modular.*.dao","com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/datasource/SingleDataSourceConfig.java
New file
@@ -0,0 +1,61 @@
package com.supersavedriving.user.config.datasource;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.supersavedriving.user.core.config.properties.DruidProperties;
import com.supersavedriving.user.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.supersavedriving.user.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();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/properties/BeetlProperties.java
New file
@@ -0,0 +1,103 @@
package com.supersavedriving.user.config.properties;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/properties/GunsProperties.java
New file
@@ -0,0 +1,103 @@
package com.supersavedriving.user.config.properties;
import com.supersavedriving.user.core.util.ToolUtil;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.File;
/**
 * 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 (ToolUtil.isEmpty(fileUploadPath)) {
            return ToolUtil.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/BeetlConfig.java
New file
@@ -0,0 +1,45 @@
package com.supersavedriving.user.config.web;
import com.supersavedriving.user.config.properties.BeetlProperties;
import com.supersavedriving.user.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.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/ShiroConfig.java
New file
@@ -0,0 +1,214 @@
package com.supersavedriving.user.config.web;
import com.supersavedriving.user.config.properties.GunsProperties;
import com.supersavedriving.user.core.intercept.GunsUserFilter;
import com.supersavedriving.user.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=="));
        manager.setCookie(rememberMeCookie);
        return manager;
    }
    /**
     * 记住密码Cookie
     */
    @Bean
    public SimpleCookie rememberMeCookie() {
        SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
        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("/api/**", "anon");
        hashMap.put("/static/**", "anon");
        hashMap.put("/gunsApi/**", "anon");
        hashMap.put("/login", "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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/config/web/WebConfig.java
New file
@@ -0,0 +1,174 @@
package com.supersavedriving.user.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.supersavedriving.user.config.properties.GunsProperties;
import com.supersavedriving.user.core.intercept.RestApiInteceptor;
import com.supersavedriving.user.core.listener.ConfigListener;
import com.supersavedriving.user.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/**");
    }
    /**
     * 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.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/aop/GlobalExceptionHandler.java
New file
@@ -0,0 +1,121 @@
package com.supersavedriving.user.core.aop;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.common.exception.InvalidKaptchaException;
import com.supersavedriving.user.core.base.tips.ErrorTip;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogManager;
import com.supersavedriving.user.core.log.factory.LogTaskFactory;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.support.HttpKit;
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;
/**
 * 全局的的异常拦截器(拦截所有的控制器)(带有@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));
        HttpKit.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 = HttpKit.getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "账号被冻结", HttpKit.getIp()));
        model.addAttribute("tips", "账号被冻结");
        return "/login.html";
    }
    /**
     * 账号密码错误异常
     */
    @ExceptionHandler(CredentialsException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public String credentials(CredentialsException e, Model model) {
        String username = HttpKit.getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "账号密码错误", HttpKit.getIp()));
        model.addAttribute("tips", "账号密码错误");
        return "/login.html";
    }
    /**
     * 验证码错误异常
     */
    @ExceptionHandler(InvalidKaptchaException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String credentials(InvalidKaptchaException e, Model model) {
        String username = HttpKit.getRequest().getParameter("username");
        LogManager.me().executeLog(LogTaskFactory.loginLog(username, "验证码错误", HttpKit.getIp()));
        model.addAttribute("tips", "验证码错误");
        return "/login.html";
    }
    /**
     * 无权访问该资源异常
     */
    @ExceptionHandler(UndeclaredThrowableException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ResponseBody
    public ErrorTip credentials(UndeclaredThrowableException e) {
        HttpKit.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));
        HttpKit.getRequest().setAttribute("tip", "服务器未知运行时异常");
        log.error("运行时异常:", e);
        return new ErrorTip(BizExceptionEnum.SERVER_ERROR.getCode(), BizExceptionEnum.SERVER_ERROR.getMessage());
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/aop/LogAop.java
New file
@@ -0,0 +1,105 @@
package com.supersavedriving.user.core.aop;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.constant.dictmap.base.AbstractDictMap;
import com.supersavedriving.user.core.log.LogManager;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.log.factory.LogTaskFactory;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.support.HttpKit;
import com.supersavedriving.user.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.supersavedriving.user.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));
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.aop;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.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.supersavedriving.user.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();
            }
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/beetl/BeetlConfiguration.java
New file
@@ -0,0 +1,71 @@
package com.supersavedriving.user.core.beetl;
import com.supersavedriving.user.core.tag.DictSelectorTag;
import com.supersavedriving.user.core.util.KaptchaUtil;
import com.supersavedriving.user.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);
                }
            }
        });
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.beetl;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.beetl.core.GroupTemplate;
import com.supersavedriving.user.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());
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/BussinessLog.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.core.common.annotion;
import com.supersavedriving.user.core.common.constant.dictmap.base.AbstractDictMap;
import com.supersavedriving.user.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;
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/Permission.java
New file
@@ -0,0 +1,22 @@
package com.supersavedriving.user.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 {};
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/annotion/ServiceLog.java
New file
@@ -0,0 +1,23 @@
package com.supersavedriving.user.core.common.annotion;
import java.lang.annotation.*;
/**
 * 接口日志注解
 */
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface ServiceLog {
    /**
     * 接口名称
     * @return
     */
    String name() default "";
    /**
     * 接口地址
     * @return
     */
    String url() default "";
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/aspect/ServiceLogAspect.java
New file
@@ -0,0 +1,72 @@
package com.supersavedriving.user.core.common.aspect;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.user.core.common.annotion.ServiceLog;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
@Aspect
@Component
public class ServiceLogAspect {
    Logger logger = LoggerFactory.getLogger("ServiceLog");
    /**
     * //切面点为标记了@ServiceLog注解的方法
     */
    @Pointcut("@annotation(com.supersavedriving.user.core.common.annotion.ServiceLog)")
    public void serviceLog(){
    }
    //环绕通知
    @Around("serviceLog()")
    @SuppressWarnings("unchecked")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        long starTime = System.currentTimeMillis();
        //通过反射获取被调用方法的Class
        Class type = joinPoint.getSignature().getDeclaringType();
        //获取类名
        String typeName = type.getSimpleName();
        //方法名
        String methodName = joinPoint.getSignature().getName();
        //获取参数列表
        Object[] args = joinPoint.getArgs();
        //参数Class的数组
        Class[] clazz = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            clazz[i] = args[i].getClass();
        }
        //通过反射获取调用的方法method
        Method method = type.getMethod(methodName, clazz);
        ServiceLog serviceLog = method.getAnnotation(ServiceLog.class);
        //获取方法的参数
        Parameter[] parameters = method.getParameters();
        JSONObject jsonObject = new JSONObject();
        for (int i = 0; i < parameters.length; i++) {
            Parameter parameter = parameters[i];
            String name = parameter.getName();
            jsonObject.put(name, args[i]);
        }
        //执行结果
        //执行目标方法,获取执行结果
        Object res = joinPoint.proceed();
        logger.debug("调用{}.{}方法成功\n" +
                "接口名称:{}\n" +
                "接口地址:{}\n" +
                "耗时:{}ms\n" +
                "参数为:{}\n" +
                "返回结果:{}", typeName, methodName, serviceLog.name(), serviceLog.url(),
                (System.currentTimeMillis() - starTime), jsonObject.toJSONString(), JSONObject.toJSONString(res));
        //返回执行结果
        return res;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/Const.java
New file
@@ -0,0 +1,36 @@
package com.supersavedriving.user.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 = "接口文档";
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/DatasourceEnum.java
New file
@@ -0,0 +1,15 @@
package com.supersavedriving.user.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";            //其他业务的数据源
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/JwtConstants.java
New file
@@ -0,0 +1,19 @@
package com.supersavedriving.user.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";
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/cache/Cache.java
New file
@@ -0,0 +1,15 @@
package com.supersavedriving.user.core.common.constant.cache;
/**
 * 所有缓存名称的集合
 *
 * @author fengshuonan
 * @date 2017-04-24 21:56
 */
public interface Cache {
    /**
     * 常量缓存
     */
    String CONSTANT = "CONSTANT";
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/cache/CacheKey.java
New file
@@ -0,0 +1,31 @@
package com.supersavedriving.user.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_";
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DeleteDict.java
New file
@@ -0,0 +1,31 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DeptDict.java
New file
@@ -0,0 +1,28 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/DictMap.java
New file
@@ -0,0 +1,24 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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() {
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/LogDict.java
New file
@@ -0,0 +1,22 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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() {
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/MenuDict.java
New file
@@ -0,0 +1,34 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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() {
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/NoticeMap.java
New file
@@ -0,0 +1,22 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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() {
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/RoleDict.java
New file
@@ -0,0 +1,31 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/UserDict.java
New file
@@ -0,0 +1,36 @@
package com.supersavedriving.user.core.common.constant.dictmap;
import com.supersavedriving.user.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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/base/AbstractDictMap.java
New file
@@ -0,0 +1,53 @@
package com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/base/SystemDict.java
New file
@@ -0,0 +1,20 @@
package com.supersavedriving.user.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() {
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/dictmap/factory/DictFieldWarpperFactory.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.core.common.constant.dictmap.factory;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.constant.factory.IConstantFactory;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.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);
            }
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/ConstantFactory.java
New file
@@ -0,0 +1,335 @@
package com.supersavedriving.user.core.common.constant.factory;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.supersavedriving.user.core.common.constant.cache.Cache;
import com.supersavedriving.user.core.common.constant.cache.CacheKey;
import com.supersavedriving.user.core.common.constant.state.ManagerStatus;
import com.supersavedriving.user.core.common.constant.state.MenuStatus;
import com.supersavedriving.user.modular.system.dao.*;
import com.supersavedriving.user.modular.system.model.*;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.support.StrKit;
import com.supersavedriving.user.core.util.Convert;
import com.supersavedriving.user.core.util.SpringContextHolder;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.dao.*;
import com.supersavedriving.user.modular.system.model.*;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;
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 {
    private RoleMapper roleMapper = SpringContextHolder.getBean(RoleMapper.class);
    private DeptMapper deptMapper = SpringContextHolder.getBean(DeptMapper.class);
    private DictMapper dictMapper = SpringContextHolder.getBean(DictMapper.class);
    private UserMapper userMapper = SpringContextHolder.getBean(UserMapper.class);
    private MenuMapper menuMapper = SpringContextHolder.getBean(MenuMapper.class);
    private NoticeMapper noticeMapper = SpringContextHolder.getBean(NoticeMapper.class);
    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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/IConstantFactory.java
New file
@@ -0,0 +1,116 @@
package com.supersavedriving.user.core.common.constant.factory;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/MutiStrFactory.java
New file
@@ -0,0 +1,96 @@
package com.supersavedriving.user.core.common.constant.factory;
import com.supersavedriving.user.core.support.StrKit;
import com.supersavedriving.user.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;
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/factory/PageFactory.java
New file
@@ -0,0 +1,38 @@
package com.supersavedriving.user.core.common.constant.factory;
import com.baomidou.mybatisplus.plugins.Page;
import com.supersavedriving.user.core.common.constant.state.Order;
import com.supersavedriving.user.core.support.HttpKit;
import com.supersavedriving.user.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;
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/BizLogType.java
New file
@@ -0,0 +1,51 @@
package com.supersavedriving.user.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;
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/ExpenseState.java
New file
@@ -0,0 +1,52 @@
package com.supersavedriving.user.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 "";
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/LogSucceed.java
New file
@@ -0,0 +1,27 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/LogType.java
New file
@@ -0,0 +1,30 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/ManagerStatus.java
New file
@@ -0,0 +1,49 @@
package com.supersavedriving.user.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 "";
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/MenuOpenStatus.java
New file
@@ -0,0 +1,50 @@
package com.supersavedriving.user.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 "";
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/MenuStatus.java
New file
@@ -0,0 +1,50 @@
package com.supersavedriving.user.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 "";
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/constant/state/Order.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/exception/BizExceptionEnum.java
New file
@@ -0,0 +1,100 @@
package com.supersavedriving.user.core.common.exception;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/common/exception/InvalidKaptchaException.java
New file
@@ -0,0 +1,10 @@
package com.supersavedriving.user.core.common.exception;
/**
 * 验证码错误异常
 *
 * @author fengshuonan
 * @date 2017-05-05 23:52
 */
public class InvalidKaptchaException extends RuntimeException {
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.intercept;
import com.supersavedriving.user.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;
                }
            }
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/intercept/RestApiInteceptor.java
New file
@@ -0,0 +1,62 @@
package com.supersavedriving.user.core.intercept;
import com.supersavedriving.user.core.base.tips.ErrorTip;
import com.supersavedriving.user.core.common.constant.JwtConstants;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.util.JwtTokenUtil;
import com.supersavedriving.user.core.util.RenderUtil;
import io.jsonwebtoken.JwtException;
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 {
    @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) {
        if (request.getServletPath().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 {
            //header没有带Bearer字段
            RenderUtil.renderJson(response, new ErrorTip(BizExceptionEnum.TOKEN_ERROR.getCode(), BizExceptionEnum.TOKEN_ERROR.getMessage()));
            return false;
        }
        return true;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/intercept/SessionHolderInterceptor.java
New file
@@ -0,0 +1,34 @@
package com.supersavedriving.user.core.intercept;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.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.supersavedriving.user.*..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();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.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());
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/LogManager.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/LogObjectHolder.java
New file
@@ -0,0 +1,34 @@
package com.supersavedriving.user.core.log;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/factory/LogFactory.java
New file
@@ -0,0 +1,47 @@
package com.supersavedriving.user.core.log.factory;
import com.supersavedriving.user.core.common.constant.state.LogSucceed;
import com.supersavedriving.user.core.common.constant.state.LogType;
import com.supersavedriving.user.modular.system.model.LoginLog;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/log/factory/LogTaskFactory.java
New file
@@ -0,0 +1,102 @@
package com.supersavedriving.user.core.log.factory;
import com.supersavedriving.user.core.common.constant.state.LogSucceed;
import com.supersavedriving.user.core.common.constant.state.LogType;
import com.supersavedriving.user.modular.system.dao.LoginLogMapper;
import com.supersavedriving.user.modular.system.dao.OperationLogMapper;
import com.supersavedriving.user.modular.system.model.LoginLog;
import com.supersavedriving.user.modular.system.model.OperationLog;
import com.supersavedriving.user.core.db.Db;
import com.supersavedriving.user.core.log.LogManager;
import com.supersavedriving.user.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);
                }
            }
        };
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/ShiroDbRealm.java
New file
@@ -0,0 +1,78 @@
package com.supersavedriving.user.core.shiro;
import com.supersavedriving.user.core.shiro.factory.IShiro;
import com.supersavedriving.user.core.shiro.factory.ShiroFactroy;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.shiro;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/ShiroUser.java
New file
@@ -0,0 +1,81 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.shiro.check;
/**
 * 检查用接口
 */
public interface ICheck {
    /**
     * 检查当前登录用户是否拥有指定的角色访问当
     */
    boolean check(Object[] permissions);
    /**
     * 检查当前登录用户是否拥有当前请求的servlet的权限
     */
    boolean checkAll();
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.shiro.check;
import com.supersavedriving.user.core.listener.ConfigListener;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.support.CollectionKit;
import com.supersavedriving.user.core.support.HttpKit;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.core.shiro.check;
import com.supersavedriving.user.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();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/factory/IShiro.java
New file
@@ -0,0 +1,50 @@
package com.supersavedriving.user.core.shiro.factory;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/shiro/factory/ShiroFactroy.java
New file
@@ -0,0 +1,98 @@
package com.supersavedriving.user.core.shiro.factory;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.constant.state.ManagerStatus;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.util.Convert;
import com.supersavedriving.user.core.util.SpringContextHolder;
import com.supersavedriving.user.modular.system.dao.MenuMapper;
import com.supersavedriving.user.modular.system.dao.UserMapper;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/tag/DictSelectorTag.java
New file
@@ -0,0 +1,201 @@
package com.supersavedriving.user.core.tag;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Dict;
import com.supersavedriving.user.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("输出字典标签错误");
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/ApiMenuFilter.java
New file
@@ -0,0 +1,36 @@
package com.supersavedriving.user.core.util;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.config.properties.GunsProperties;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/Contrast.java
New file
@@ -0,0 +1,211 @@
package com.supersavedriving.user.core.util;
import com.supersavedriving.user.core.common.constant.dictmap.base.AbstractDictMap;
import com.supersavedriving.user.core.common.constant.dictmap.factory.DictFieldWarpperFactory;
import com.supersavedriving.user.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.err.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();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/JwtTokenUtil.java
New file
@@ -0,0 +1,127 @@
package com.supersavedriving.user.core.util;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/core/util/KaptchaUtil.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.user.core.util;
import com.supersavedriving.user.config.properties.GunsProperties;
/**
 * 验证码工具类
 */
public class KaptchaUtil {
    /**
     * 获取验证码开关
     */
    public static Boolean getKaptchaOnOff() {
        return SpringContextHolder.getBean(GunsProperties.class).getKaptchaOpen();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/ApiController.java
New file
@@ -0,0 +1,80 @@
package com.supersavedriving.user.modular.api;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.base.tips.ErrorTip;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.util.JwtTokenUtil;
import com.supersavedriving.user.modular.system.dao.UserMapper;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/AppUserController.java
New file
@@ -0,0 +1,66 @@
package com.supersavedriving.user.modular.api;
import com.supersavedriving.user.core.common.annotion.ServiceLog;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.service.IAppUserService;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import com.supersavedriving.user.modular.system.warpper.ResponseWarpper;
import com.supersavedriving.user.modular.system.warpper.SignInToRegister;
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;
/**
 * 用户控制器
 */
@RestController
@RequestMapping("")
public class AppUserController {
    @Autowired
    private IAppUserService appUserService;
    @ResponseBody
    @PostMapping("/base/appUser/appUserLogin")
    @ServiceLog(name = "微信登录", url = "/base/appUser/appUserLogin")
    @ApiOperation(value = "微信登录", tags = {"用户端-首页"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "微信jscode", name = "jscode", required = true, dataType = "string"),
    })
    public ResponseWarpper appUserLogin(String jscode){
        if(ToolUtil.isEmpty(jscode)){
            return ResponseWarpper.success(ResultUtil.paranErr("jscode"));
        }
        try {
            ResultUtil resultUtil = appUserService.appUserLogin(jscode);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
    @ResponseBody
    @PostMapping("/base/appUser/signInToRegister")
    @ServiceLog(name = "微信手机授权登录", url = "/base/appUser/signInToRegister")
    @ApiOperation(value = "微信手机授权登录", tags = {"用户端-首页"}, notes = "")
    @ApiImplicitParams({
    })
    public ResponseWarpper signInToRegister(SignInToRegister signInToRegister){
        try {
            ResultUtil resultUtil = appUserService.signInToRegister(signInToRegister);
            return ResponseWarpper.success(resultUtil);
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/api/HtmlController.java
New file
@@ -0,0 +1,50 @@
package com.supersavedriving.user.modular.api;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.user.core.common.annotion.ServiceLog;
import com.supersavedriving.user.modular.system.model.Html;
import com.supersavedriving.user.modular.system.service.IHtmlService;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import com.supersavedriving.user.modular.system.warpper.ResponseWarpper;
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;
/**
 * 协议控制器
 */
@RestController
@RequestMapping("")
public class HtmlController {
    @Autowired
    private IHtmlService htmlService;
    @ResponseBody
    @PostMapping("/base/html/queryHtml")
    @ServiceLog(name = "获取各种协议和说明", url = "/base/html/queryHtml")
    @ApiOperation(value = "获取各种协议和说明", tags = {"用户端-首页"}, notes = "")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "类型(1=用户协议,2=隐私政策,3=法律条款,4=代驾服务协议,5=个人信息处理规则,6=积分说明,7=佣金规则说明,8=行程录音说明,9=预估价格说明,10=加盟基本要求,11=加盟流程,12=起步价说明,13=注销协议,14=关于我们,15=司机消单说明)", name = "type", required = true, dataType = "int"),
    })
    public ResponseWarpper<String> queryHtml(Integer type){
        if(null == type){
            return ResponseWarpper.success(ResultUtil.paranErr("type"));
        }
        try {
            Html html = htmlService.selectOne(new EntityWrapper<Html>().eq("type", type));
            return ResponseWarpper.success(null == html ? "" : html.getHtml());
        }catch (Exception e){
            e.printStackTrace();
            return new ResponseWarpper(500, e.getMessage());
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/controller/CodeController.java
New file
@@ -0,0 +1,61 @@
package com.supersavedriving.user.modular.code.controller;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.config.properties.DruidProperties;
import com.supersavedriving.user.generator.action.config.WebGeneratorConfig;
import com.supersavedriving.user.generator.action.model.GenQo;
import com.supersavedriving.user.modular.code.factory.DefaultTemplateFactory;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/factory/DefaultTemplateFactory.java
New file
@@ -0,0 +1,61 @@
package com.supersavedriving.user.modular.code.factory;
import com.supersavedriving.user.GunsApplication;
import com.supersavedriving.user.core.CoreFlag;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/code/service/TableService.java
New file
@@ -0,0 +1,29 @@
package com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthIntercepter.java
New file
@@ -0,0 +1,37 @@
package com.supersavedriving.user.modular.system.auth;
import com.alibaba.fastjson.JSON;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class AuthIntercepter implements HandlerInterceptor {
    private final static Logger log = LoggerFactory.getLogger(AuthIntercepter.class);
    @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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthService.java
New file
@@ -0,0 +1,49 @@
package com.supersavedriving.user.modular.system.auth;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
@Service
public class AuthService {
    private final static Logger log = LoggerFactory.getLogger(AuthService.class);
    public static final AuthService me = new AuthService();
    /**
     * 鉴权
     * @param appid
     * @param sign
     * @param requset
     * @return
     */
    public ResultUtil checkSyncAuth(String appid, String sign, HttpServletRequest requset) {
        try {
            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();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/AuthenticationKit.java
New file
@@ -0,0 +1,232 @@
package com.supersavedriving.user.modular.system.auth;
import org.apache.tomcat.util.codec.binary.Base64;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
 *
 * 接口鉴权工具类
 *
 * @author gwx 2017-12-23
 *
 */
public class AuthenticationKit {
    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) {
        StringBuilder strBuilder = new StringBuilder();
//        if(StringUtils.isNotBlank(url) && url.lastIndexOf("?")==-1){
//            strBuilder.append(url).append("?");
//        }
        Set es = params.entrySet();//所有参与传参的参数按照accsii排序(升序)
        Iterator it = es.iterator();
        while(it.hasNext()) {
            Map.Entry entry = (Map.Entry)it.next();
            String k = (String)entry.getKey();
            Object v = entry.getValue();
            if(null != v && !"".equals(v)) {
                strBuilder.append(k + "=" + v + "&");
            }
        }
        return strBuilder.substring(0, strBuilder.length() - 1);
//        for (String key : params.keySet()) {
//            if (params.get(key) != null) {
//                String lowerKey = key.toLowerCase();
//                String encodeKey = lowerKey;
//                String encodedValue = params.get(key);
//                if (urlEncode){
//                    encodeKey = UrlEncoderUtils.encode(lowerKey);
//                    encodedValue = UrlEncoderUtils.encode(encodedValue);
//                }
//                if (!seeOne) {
//                    seeOne = true;
//                } else {
//                    strBuilder.append("&");
//                }
//                strBuilder.append(encodeKey).append("=").append(encodedValue);
//            }
//        }
//        return strBuilder.toString();
    }
    /**
     * 加密签名路径生成签名
     *
     * @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;
    }
    /**
     * 返回鉴权 签名路径
     *
     * @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访问地址 "/apid"
     * @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访问地址 "/apid"
     * @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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/Configuration.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.modular.system.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/**");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/HMACSHA1.java
New file
@@ -0,0 +1,63 @@
package com.supersavedriving.user.modular.system.auth;
import org.apache.commons.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();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/HashKit.java
New file
@@ -0,0 +1,109 @@
package com.supersavedriving.user.modular.system.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/auth/UrlEncoderUtils.java
New file
@@ -0,0 +1,44 @@
package com.supersavedriving.user.modular.system.auth;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class UrlEncoderUtils {
    private static final String PATH_DELIMITER = "/";
    private static final Logger log = LoggerFactory.getLogger(UrlEncoderUtils.class);
    public static String encode(String originUrl) {
        try {
            return URLEncoder.encode(originUrl, "UTF-8").replace("+", "%20").replace("*", "%2A")
                    .replace("%7E", "~");
        } catch (UnsupportedEncodingException e) {
            log.error("URLEncoder error, encode utf8, exception: {}", e);
        }
        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();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/BlackboardController.java
New file
@@ -0,0 +1,35 @@
package com.supersavedriving.user.modular.system.controller;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.modular.system.service.INoticeService;
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 java.util.List;
import java.util.Map;
/**
 * 总览信息
 *
 * @author fengshuonan
 * @Date 2017年3月4日23:05:54
 */
@Controller
@RequestMapping("/blackboard")
public class BlackboardController extends BaseController {
    @Autowired
    private INoticeService noticeService;
    /**
     * 跳转到黑板
     */
    @RequestMapping("")
    public String blackboard(Model model) {
        List<Map<String, Object>> notices = noticeService.list(null);
        model.addAttribute("noticeList", notices);
        return "/blackboard.html";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/DeptController.java
New file
@@ -0,0 +1,164 @@
package com.supersavedriving.user.modular.system.controller;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.dictmap.DeptDict;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Dept;
import com.supersavedriving.user.modular.system.service.IDeptService;
import com.supersavedriving.user.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";
    }
    /**
     * 跳转到修改部门
     */
    @Permission
    @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列表
     */
    @RequestMapping(value = "/tree")
    @ResponseBody
    public List<ZTreeNode> tree() {
        List<ZTreeNode> tree = this.deptService.tree();
        tree.add(ZTreeNode.createParent());
        return tree;
    }
    /**
     * 新增部门
     */
    @BussinessLog(value = "添加部门", key = "simplename", dict = DeptDict.class)
    @RequestMapping(value = "/add")
    @Permission
    @ResponseBody
    public Object add(Dept dept) {
        if (ToolUtil.isOneEmpty(dept, dept.getSimplename())) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        //完善pids,根据pid拿到pid的pids
        deptSetPids(dept);
        return this.deptService.insert(dept);
    }
    /**
     * 获取所有部门列表
     */
    @RequestMapping(value = "/list")
    @Permission
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.deptService.list(condition);
        return super.warpObject(new DeptWarpper(list));
    }
    /**
     * 部门详情
     */
    @RequestMapping(value = "/detail/{deptId}")
    @Permission
    @ResponseBody
    public Object detail(@PathVariable("deptId") Integer deptId) {
        return deptService.selectById(deptId);
    }
    /**
     * 修改部门
     */
    @BussinessLog(value = "修改部门", key = "simplename", dict = DeptDict.class)
    @RequestMapping(value = "/update")
    @Permission
    @ResponseBody
    public Object update(Dept dept) {
        if (ToolUtil.isEmpty(dept) || dept.getId() == null) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        deptSetPids(dept);
        deptService.updateById(dept);
        return SUCCESS_TIP;
    }
    /**
     * 删除部门
     */
    @BussinessLog(value = "删除部门", key = "deptId", dict = DeptDict.class)
    @RequestMapping(value = "/delete")
    @Permission
    @ResponseBody
    public Object delete(@RequestParam Integer deptId) {
        //缓存被删除的部门名称
        LogObjectHolder.me().set(ConstantFactory.me().getDeptName(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 + "],");
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/DictController.java
New file
@@ -0,0 +1,142 @@
package com.supersavedriving.user.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.dictmap.DictMap;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Dict;
import com.supersavedriving.user.modular.system.service.IDictService;
import com.supersavedriving.user.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";
    }
    /**
     * 跳转到修改字典
     */
    @Permission(Const.ADMIN_NAME)
    @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:冻结"
     */
    @BussinessLog(value = "添加字典记录", key = "dictName,dictValues", dict = DictMap.class)
    @RequestMapping(value = "/add")
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 获取所有字典列表
     */
    @RequestMapping(value = "/list")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.dictService.list(condition);
        return super.warpObject(new DictWarpper(list));
    }
    /**
     * 字典详情
     */
    @RequestMapping(value = "/detail/{dictId}")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object detail(@PathVariable("dictId") Integer dictId) {
        return dictService.selectById(dictId);
    }
    /**
     * 修改字典
     */
    @BussinessLog(value = "修改字典", key = "dictName,dictValues", dict = DictMap.class)
    @RequestMapping(value = "/update")
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 删除字典记录
     */
    @BussinessLog(value = "删除字典记录", key = "dictId", dict = DictMap.class)
    @RequestMapping(value = "/delete")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object delete(@RequestParam Integer dictId) {
        //缓存被删除的名称
        LogObjectHolder.me().set(ConstantFactory.me().getDictName(dictId));
        this.dictService.delteDict(dictId);
        return SUCCESS_TIP;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/KaptchaController.java
New file
@@ -0,0 +1,114 @@
package com.supersavedriving.user.modular.system.controller;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import com.supersavedriving.user.config.properties.GunsProperties;
import com.supersavedriving.user.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;
/**
 * 验证码生成
 *
 * @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
        BufferedImage bi = producer.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();
            }
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LogController.java
New file
@@ -0,0 +1,84 @@
package com.supersavedriving.user.modular.system.controller;
import com.baomidou.mybatisplus.mapper.SqlRunner;
import com.baomidou.mybatisplus.plugins.Page;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.factory.PageFactory;
import com.supersavedriving.user.core.common.constant.state.BizLogType;
import com.supersavedriving.user.core.support.BeanKit;
import com.supersavedriving.user.modular.system.model.OperationLog;
import com.supersavedriving.user.modular.system.service.IOperationLogService;
import com.supersavedriving.user.modular.system.warpper.LogWarpper;
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 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("/log")
public class LogController extends BaseController {
    private static String PREFIX = "/system/log/";
    @Autowired
    private IOperationLogService operationLogService;
    /**
     * 跳转到日志管理的首页
     */
    @RequestMapping("")
    public String index() {
        return PREFIX + "log.html";
    }
    /**
     * 查询操作日志列表
     */
    @RequestMapping("/list")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object list(@RequestParam(required = false) String beginTime, @RequestParam(required = false) String endTime, @RequestParam(required = false) String logName, @RequestParam(required = false) Integer logType) {
        Page<OperationLog> page = new PageFactory<OperationLog>().defaultPage();
        List<Map<String, Object>> result = operationLogService.getOperationLogs(page, beginTime, endTime, logName, BizLogType.valueOf(logType), page.getOrderByField(), page.isAsc());
        page.setRecords((List<OperationLog>) new LogWarpper(result).warp());
        return super.packForBT(page);
    }
    /**
     * 查询操作日志详情
     */
    @RequestMapping("/detail/{id}")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object detail(@PathVariable Integer id) {
        OperationLog operationLog = operationLogService.selectById(id);
        Map<String, Object> stringObjectMap = BeanKit.beanToMap(operationLog);
        return super.warpObject(new LogWarpper(stringObjectMap));
    }
    /**
     * 清空日志
     */
    @BussinessLog(value = "清空业务日志")
    @RequestMapping("/delLog")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object delLog() {
        SqlRunner.db().delete("delete from sys_operation_log");
        return SUCCESS_TIP;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LoginController.java
New file
@@ -0,0 +1,133 @@
package com.supersavedriving.user.modular.system.controller;
import com.google.code.kaptcha.Constants;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.exception.InvalidKaptchaException;
import com.supersavedriving.user.core.log.LogManager;
import com.supersavedriving.user.core.log.factory.LogTaskFactory;
import com.supersavedriving.user.core.node.MenuNode;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.util.ApiMenuFilter;
import com.supersavedriving.user.core.util.KaptchaUtil;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.User;
import com.supersavedriving.user.modular.system.service.IMenuService;
import com.supersavedriving.user.modular.system.service.IUserService;
import com.supersavedriving.user.core.support.HttpKit;
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.List;
/**
 * 登录控制器
 *
 * @author fengshuonan
 * @Date 2017年1月10日 下午8:25:24
 */
@Controller
public class LoginController extends BaseController {
    @Autowired
    private IMenuService menuService;
    @Autowired
    private IUserService userService;
    /**
     * 跳转到主页
     */
    @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() {
        if (ShiroKit.isAuthenticated() || ShiroKit.getUser() != null) {
            return REDIRECT + "/";
        } else {
            return "/login.html";
        }
    }
    /**
     * 点击登录执行的动作
     */
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public String loginVali() {
        String username = super.getPara("username").trim();
        String password = super.getPara("password").trim();
        String remember = super.getPara("remember");
        //验证验证码是否正确
        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)) {
                throw new InvalidKaptchaException();
            }
        }
        Subject currentUser = ShiroKit.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(username, password.toCharArray());
        if ("on".equals(remember)) {
            token.setRememberMe(true);
        } else {
            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(), HttpKit.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(), HttpKit.getIp()));
        ShiroKit.getSubject().logout();
        deleteAllCookie();
        return REDIRECT + "/login";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/LoginLogController.java
New file
@@ -0,0 +1,69 @@
package com.supersavedriving.user.modular.system.controller;
import com.baomidou.mybatisplus.mapper.SqlRunner;
import com.baomidou.mybatisplus.plugins.Page;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.factory.PageFactory;
import com.supersavedriving.user.modular.system.model.LoginLog;
import com.supersavedriving.user.modular.system.service.ILoginLogService;
import com.supersavedriving.user.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";
    }
    /**
     * 查询登录日志列表
     */
    @RequestMapping("/list")
    @Permission(Const.ADMIN_NAME)
    @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);
    }
    /**
     * 清空日志
     */
    @BussinessLog("清空登录日志")
    @RequestMapping("/delLoginLog")
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Object delLog() {
        SqlRunner.db().delete("delete from sys_login_log");
        return SUCCESS_TIP;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/MenuController.java
New file
@@ -0,0 +1,244 @@
package com.supersavedriving.user.modular.system.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.base.tips.Tip;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.dictmap.MenuDict;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.constant.state.MenuStatus;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.core.support.BeanKit;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Menu;
import com.supersavedriving.user.modular.system.service.IMenuService;
import com.supersavedriving.user.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";
    }
    /**
     * 跳转到菜单详情列表页面
     */
    @Permission(Const.ADMIN_NAME)
    @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";
    }
    /**
     * 修该菜单
     */
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 获取菜单列表
     */
    @Permission(Const.ADMIN_NAME)
    @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));
    }
    /**
     * 新增菜单
     */
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 删除菜单
     */
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 查看菜单
     */
    @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;
    }
    /**
     * 获取菜单列表(首页用)
     */
    @RequestMapping(value = "/menuTreeList")
    @ResponseBody
    public List<ZTreeNode> menuTreeList() {
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList();
        return roleTreeList;
    }
    /**
     * 获取菜单列表(选择父级菜单用)
     */
    @RequestMapping(value = "/selectMenuTreeList")
    @ResponseBody
    public List<ZTreeNode> selectMenuTreeList() {
        List<ZTreeNode> roleTreeList = this.menuService.menuTreeList();
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
    /**
     * 获取角色列表
     */
    @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() + "],");
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/NoticeController.java
New file
@@ -0,0 +1,138 @@
package com.supersavedriving.user.modular.system.controller;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.constant.dictmap.NoticeMap;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Notice;
import com.supersavedriving.user.modular.system.service.INoticeService;
import com.supersavedriving.user.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";
    }
    /**
     * 跳转到修改通知
     */
    @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";
    }
    /**
     * 跳转到首页通知
     */
    @RequestMapping("/hello")
    public String hello() {
        List<Map<String, Object>> notices = noticeService.list(null);
        super.setAttr("noticeList",notices);
        return "/blackboard.html";
    }
    /**
     * 获取通知列表
     */
    @RequestMapping(value = "/list")
    @ResponseBody
    public Object list(String condition) {
        List<Map<String, Object>> list = this.noticeService.list(condition);
        return super.warpObject(new NoticeWrapper(list));
    }
    /**
     * 新增通知
     */
    @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;
    }
    /**
     * 删除通知
     */
    @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;
    }
    /**
     * 修改通知
     */
    @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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/RoleController.java
New file
@@ -0,0 +1,230 @@
package com.supersavedriving.user.modular.system.controller;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.base.tips.Tip;
import com.supersavedriving.user.core.cache.CacheKit;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.cache.Cache;
import com.supersavedriving.user.core.common.constant.dictmap.RoleDict;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.core.util.Convert;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.Role;
import com.supersavedriving.user.modular.system.model.User;
import com.supersavedriving.user.modular.system.service.IRoleService;
import com.supersavedriving.user.modular.system.service.IUserService;
import com.supersavedriving.user.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";
    }
    /**
     * 跳转到修改角色
     */
    @Permission
    @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";
    }
    /**
     * 跳转到角色分配
     */
    @Permission
    @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";
    }
    /**
     * 获取角色列表
     */
    @Permission
    @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));
    }
    /**
     * 角色新增
     */
    @RequestMapping(value = "/add")
    @BussinessLog(value = "添加角色", key = "name", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @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;
    }
    /**
     * 角色修改
     */
    @RequestMapping(value = "/edit")
    @BussinessLog(value = "修改角色", key = "name", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip edit(@Valid Role role, BindingResult result) {
        if (result.hasErrors()) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        this.roleService.updateById(role);
        //删除缓存
        CacheKit.removeAll(Cache.CONSTANT);
        return SUCCESS_TIP;
    }
    /**
     * 删除角色
     */
    @RequestMapping(value = "/remove")
    @BussinessLog(value = "删除角色", key = "roleId", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @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));
        this.roleService.delRoleById(roleId);
        //删除缓存
        CacheKit.removeAll(Cache.CONSTANT);
        return SUCCESS_TIP;
    }
    /**
     * 查看角色
     */
    @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;
    }
    /**
     * 配置权限
     */
    @RequestMapping("/setAuthority")
    @BussinessLog(value = "配置权限", key = "roleId,ids", dict = RoleDict.class)
    @Permission(Const.ADMIN_NAME)
    @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);
        return SUCCESS_TIP;
    }
    /**
     * 获取角色列表
     */
    @RequestMapping(value = "/roleTreeList")
    @ResponseBody
    public List<ZTreeNode> roleTreeList() {
        List<ZTreeNode> roleTreeList = this.roleService.roleTreeList();
        roleTreeList.add(ZTreeNode.createParent());
        return roleTreeList;
    }
    /**
     * 获取角色列表
     */
    @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;
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/controller/UserMgrController.java
New file
@@ -0,0 +1,373 @@
package com.supersavedriving.user.modular.system.controller;
import com.supersavedriving.user.config.properties.GunsProperties;
import com.supersavedriving.user.core.base.controller.BaseController;
import com.supersavedriving.user.core.base.tips.Tip;
import com.supersavedriving.user.core.common.annotion.BussinessLog;
import com.supersavedriving.user.core.common.annotion.Permission;
import com.supersavedriving.user.core.common.constant.Const;
import com.supersavedriving.user.core.common.constant.dictmap.UserDict;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.common.constant.state.ManagerStatus;
import com.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.datascope.DataScope;
import com.supersavedriving.user.core.db.Db;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.core.log.LogObjectHolder;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.dao.UserMapper;
import com.supersavedriving.user.modular.system.factory.UserFactory;
import com.supersavedriving.user.modular.system.model.User;
import com.supersavedriving.user.modular.system.service.IUserService;
import com.supersavedriving.user.modular.system.transfer.UserDto;
import com.supersavedriving.user.modular.system.warpper.UserWarpper;
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.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
 * 系统管理员控制器
 *
 * @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自带的权限检查
    @Permission
    @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";
    }
    /**
     * 跳转到编辑管理员页面
     */
    @Permission
    @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";
    }
    /**
     * 跳转到查看用户详情页面
     */
    @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";
    }
    /**
     * 修改当前用户的密码
     */
    @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);
        String oldMd5 = ShiroKit.md5(oldPwd, user.getSalt());
        if (user.getPassword().equals(oldMd5)) {
            String newMd5 = ShiroKit.md5(newPwd, user.getSalt());
            user.setPassword(newMd5);
            user.updateById();
            return SUCCESS_TIP;
        } else {
            throw new GunsException(BizExceptionEnum.OLD_PWD_NOT_RIGHT);
        }
    }
    /**
     * 查询管理员列表
     */
    @RequestMapping("/list")
    @Permission
    @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();
        }
    }
    /**
     * 添加管理员
     */
    @RequestMapping("/add")
    @BussinessLog(value = "添加管理员", key = "account", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @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
     */
    @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);
            }
        }
    }
    /**
     * 删除管理员(逻辑删除)
     */
    @RequestMapping("/delete")
    @BussinessLog(value = "删除管理员", key = "userId", dict = UserDict.class)
    @Permission
    @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);
        this.userService.setStatus(userId, ManagerStatus.DELETED.getCode());
        return SUCCESS_TIP;
    }
    /**
     * 查看管理员详情
     */
    @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);
    }
    /**
     * 重置管理员的密码
     */
    @RequestMapping("/reset")
    @BussinessLog(value = "重置管理员密码", key = "userId", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @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.setSalt(ShiroKit.getRandomSalt(5));
        user.setPassword(ShiroKit.md5(Const.DEFAULT_PWD, user.getSalt()));
        this.userService.updateById(user);
        return SUCCESS_TIP;
    }
    /**
     * 冻结用户
     */
    @RequestMapping("/freeze")
    @BussinessLog(value = "冻结用户", key = "userId", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @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);
        this.userService.setStatus(userId, ManagerStatus.FREEZED.getCode());
        return SUCCESS_TIP;
    }
    /**
     * 解除冻结用户
     */
    @RequestMapping("/unfreeze")
    @BussinessLog(value = "解除冻结用户", key = "userId", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @ResponseBody
    public Tip unfreeze(@RequestParam Integer userId) {
        if (ToolUtil.isEmpty(userId)) {
            throw new GunsException(BizExceptionEnum.REQUEST_NULL);
        }
        assertAuth(userId);
        this.userService.setStatus(userId, ManagerStatus.OK.getCode());
        return SUCCESS_TIP;
    }
    /**
     * 分配角色
     */
    @RequestMapping("/setRole")
    @BussinessLog(value = "分配角色", key = "userId,roleIds", dict = UserDict.class)
    @Permission(Const.ADMIN_NAME)
    @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);
        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);
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/AppUserMapper.java
New file
@@ -0,0 +1,7 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.modular.system.model.AppUser;
public interface AppUserMapper extends BaseMapper<AppUser> {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DeptMapper.java
New file
@@ -0,0 +1,31 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/DictMapper.java
New file
@@ -0,0 +1,34 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/HtmlMapper.java
New file
@@ -0,0 +1,11 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.modular.system.model.Html;
/**
 * @author 39373
 * @date 2023/2/26 17:29
 */
public interface HtmlMapper extends BaseMapper<Html> {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/LoginLogMapper.java
New file
@@ -0,0 +1,27 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/MenuMapper.java
New file
@@ -0,0 +1,80 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.core.node.MenuNode;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/NoticeMapper.java
New file
@@ -0,0 +1,25 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/OperationLogMapper.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RegionMapper.java
New file
@@ -0,0 +1,12 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.modular.system.model.Region;
import org.apache.ibatis.annotations.Param;
public interface RegionMapper extends BaseMapper<Region> {
    Region query(@Param("code") String code);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RelationMapper.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.modular.system.model.Relation;
/**
 * <p>
  * 角色和菜单关联表 Mapper 接口
 * </p>
 *
 * @author stylefeng
 * @since 2017-07-11
 */
public interface RelationMapper extends BaseMapper<Relation> {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/RoleMapper.java
New file
@@ -0,0 +1,53 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/UserMapper.java
New file
@@ -0,0 +1,45 @@
package com.supersavedriving.user.modular.system.dao;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.supersavedriving.user.core.datascope.DataScope;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/AppUserMapper.xml
New file
@@ -0,0 +1,25 @@
<?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.supersavedriving.user.modular.system.dao.AppUserMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.AppUser">
        <id column="id" property="id"/>
        <result column="nickname" property="nickname"/>
        <result column="phone" property="phone"/>
        <result column="sex" property="sex"/>
        <result column="avatar" property="avatar"/>
        <result column="openid" property="openid"/>
        <result column="unionid" property="unionid"/>
        <result column="emergencyContact" property="emergencyContact"/>
        <result column="emergencyPhone" property="emergencyPhone"/>
        <result column="accountBalance" property="accountBalance"/>
        <result column="userTagId" property="userTagId"/>
        <result column="status" property="status"/>
        <result column="createTime" property="createTime"/>
        <result column="is_exception" property="isException"/>
        <result column="remark" property="remark"/>
        <result column="inviterType" property="inviterType"/>
        <result column="inviterId" property="inviterId"/>
    </resultMap>
</mapper>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.DeptMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.DictMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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="dict">
        select
        <include refid="Base_Column_List"/>
        from sys_dict
        where code = #{code}
    </select>
    <select id="selectByParentCode" resultType="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>
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/HtmlMapper.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.supersavedriving.user.modular.system.dao.HtmlMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.Html">
        <id column="id" property="id"/>
        <result column="type" property="type"/>
        <result column="html" property="html"/>
        <result column="createTime" property="createTime"/>
    </resultMap>
</mapper>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.LoginLogMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.MenuMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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.supersavedriving.user.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.supersavedriving.user.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.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.NoticeMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.OperationLogMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/RegionMapper.xml
New file
@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.supersavedriving.user.modular.system.dao.RegionMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.Region">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="code" property="code" />
        <result column="citycode" property="citycode" />
        <result column="parent_id" property="parentId" />
        <result column="english" property="english" />
    </resultMap>
    <select id="query" resultType="Region">
        select
        id as id,
        name as name,
        code as code,
        citycode as citycode,
        parent_id as parentId,
        english as english
        from t_region where code = #{code}
    </select>
</mapper>
user/guns-admin/src/main/java/com/supersavedriving/user/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.supersavedriving.user.modular.system.dao.RelationMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.modular.system.model.Relation">
        <id column="id" property="id" />
        <result column="menuid" property="menuid" />
        <result column="roleid" property="roleid" />
    </resultMap>
</mapper>
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/RoleMapper.xml
New file
@@ -0,0 +1,79 @@
<?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.supersavedriving.user.modular.system.dao.RoleMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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>
    </select>
    <delete id="deleteRolesById">
        delete from sys_relation where roleid = #{roleId}
    </delete>
    <select id="roleTreeList" resultType="com.supersavedriving.user.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.supersavedriving.user.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>
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/dao/mapping/UserMapper.xml
New file
@@ -0,0 +1,77 @@
<?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.supersavedriving.user.modular.system.dao.UserMapper">
    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.supersavedriving.user.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" />
    </resultMap>
    <sql id="Base_Column_List">
        id, account, name, birthday, sex, email, avatar,
        phone, roleid,
        deptid, status,
        createtime, version
    </sql>
    <sql id="Base_Column_List_With_Pwd">
        id, account, name, birthday,password, sex, email, avatar,
        phone, roleid,salt,
        deptid, status,
        createtime, version
    </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="user">
        select
        <include refid="Base_Column_List_With_Pwd" />
        from sys_user where account = #{account} and status != 3
    </select>
</mapper>
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/factory/UserFactory.java
New file
@@ -0,0 +1,54 @@
package com.supersavedriving.user.modular.system.factory;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.model.User;
import com.supersavedriving.user.modular.system.transfer.UserDto;
import org.springframework.beans.BeanUtils;
/**
 * 用户创建工厂
 *
 * @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);
            return user;
        }
    }
    public static User editUser(UserDto newUser, User oldUser) {
        if (newUser == null || oldUser == null) {
            return oldUser;
        } else {
            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;
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/AppUser.java
New file
@@ -0,0 +1,103 @@
package com.supersavedriving.user.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;
/**
 * 用户
 */
@Data
@TableName("t_app_user")
public class AppUser {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 昵称
     */
    @TableField("nickname")
    private String nickname;
    /**
     * 电话
     */
    @TableField("phone")
    private String phone;
    /**
     * 性别(1=男,2=女)
     */
    @TableField("sex")
    private Integer sex;
    /**
     * 头像
     */
    @TableField("avatar")
    private String avatar;
    /**
     * 微信openid
     */
    @TableField("openid")
    private String openid;
    /**
     * 微信unionid
     */
    @TableField("unionid")
    private String unionid;
    /**
     * 紧急联系人
     */
    @TableField("emergencyContact")
    private String emergencyContact;
    /**
     * 紧急联系人电话
     */
    @TableField("emergencyPhone")
    private String emergencyPhone;
    /**
     * 账户余额
     */
    @TableField("accountBalance")
    private Double accountBalance;
    /**
     * 用户标签id
     */
    @TableField("userTagId")
    private Integer userTagId;
    /**
     * 状态(1=正常,2=冻结,3=删除)
     */
    @TableField("status")
    private Integer status;
    /**
     * 添加时间
     */
    @TableField("createTime")
    private Date createTime;
    /**
     * 是否异常 1正常 2异常
     */
    @TableField("is_exception")
    private Integer isException;
    /**
     * 启动冻结理由
     */
    @TableField("remark")
    private String remark;
    /**
     * 邀约人类型(1=用户,2=司机)
     */
    @TableField("inviterType")
    private Integer inviterType;
    /**
     * 邀约人id
     */
    @TableField("inviterId")
    private Integer inviterId;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Dept.java
New file
@@ -0,0 +1,140 @@
package com.supersavedriving.user.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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Dict.java
New file
@@ -0,0 +1,116 @@
package com.supersavedriving.user.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 + '\'' +
                '}';
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Html.java
New file
@@ -0,0 +1,38 @@
package com.supersavedriving.user.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;
/**
 * 协议
 */
@Data
@TableName("t_html")
public class Html {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 类型(1=用户协议,2=隐私政策,3=法律条款,4=代驾服务协议,5=个人信息处理规则,6=积分说明,7=佣金规则说明,8=行程录音说明,9=预估价格说明,10=加盟基本要求,11=加盟流程,12=起步价说明,13=注销协议,14=关于我们)
     */
    @TableField("type")
    private Integer type;
    /**
     * H5内容
     */
    @TableField("html")
    private String html;
    /**
     * 添加时间
     */
    @TableField("createTime")
    private Date createTime;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/LoginLog.java
New file
@@ -0,0 +1,128 @@
package com.supersavedriving.user.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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Menu.java
New file
@@ -0,0 +1,208 @@
package com.supersavedriving.user.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 +
                "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Notice.java
New file
@@ -0,0 +1,115 @@
package com.supersavedriving.user.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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/OperationLog.java
New file
@@ -0,0 +1,154 @@
package com.supersavedriving.user.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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Region.java
New file
@@ -0,0 +1,104 @@
package com.supersavedriving.user.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;
/**
 * 省市区
 */
@TableName("t_region")
public class Region {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    @TableField("id")
    private Integer id;
    /**
     * 城市名称
     */
    @TableField("name")
    private String name;
    /**
     * 城市行政code
     */
    @TableField("code")
    private String code;
    /**
     * 区号code
     */
    @TableField("citycode")
    private String citycode;
    /**
     * 父级id
     */
    @TableField("parent_id")
    private Integer parentId;
    /**
     * 英文
     */
    @TableField("english")
    private String english;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getCitycode() {
        return citycode;
    }
    public void setCitycode(String citycode) {
        this.citycode = citycode;
    }
    public Integer getParentId() {
        return parentId;
    }
    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }
    public String getEnglish() {
        return english;
    }
    public void setEnglish(String english) {
        this.english = english;
    }
    @Override
    public String toString() {
        return "Region{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", code='" + code + '\'' +
                ", citycode='" + citycode + '\'' +
                ", parentId=" + parentId +
                ", english='" + english + '\'' +
                '}';
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Relation.java
New file
@@ -0,0 +1,75 @@
package com.supersavedriving.user.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 +
                "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/Role.java
New file
@@ -0,0 +1,127 @@
package com.supersavedriving.user.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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/model/User.java
New file
@@ -0,0 +1,232 @@
package com.supersavedriving.user.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_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;
    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;
    }
    @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 +
            "}";
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IAppUserService.java
New file
@@ -0,0 +1,27 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.modular.system.model.AppUser;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import com.supersavedriving.user.modular.system.warpper.SignInToRegister;
public interface IAppUserService extends IService<AppUser> {
    /**
     * 用户登录
     * @param jscode
     * @return
     * @throws Exception
     */
    ResultUtil appUserLogin(String jscode) throws Exception;
    /**
     * 微信授权注册登录
     * @param signInToRegister
     * @return
     * @throws Exception
     */
    ResultUtil signInToRegister(SignInToRegister signInToRegister) throws Exception;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDeptService.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IDictService.java
New file
@@ -0,0 +1,48 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IHtmlService.java
New file
@@ -0,0 +1,11 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.modular.system.model.Html;
/**
 * @author 39373
 * @date 2023/2/26 17:30
 */
public interface IHtmlService extends IService<Html> {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/ILoginLogService.java
New file
@@ -0,0 +1,24 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IMenuService.java
New file
@@ -0,0 +1,94 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.core.node.MenuNode;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/INoticeService.java
New file
@@ -0,0 +1,23 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IOperationLogService.java
New file
@@ -0,0 +1,24 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IRelationService.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.modular.system.model.Relation;
/**
 * <p>
 * 角色和菜单关联表 服务类
 * </p>
 *
 * @author stylefeng123
 * @since 2018-02-22
 */
public interface IRelationService extends IService<Relation> {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IRoleService.java
New file
@@ -0,0 +1,68 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/IUserService.java
New file
@@ -0,0 +1,46 @@
package com.supersavedriving.user.modular.system.service;
import com.baomidou.mybatisplus.service.IService;
import com.supersavedriving.user.core.datascope.DataScope;
import com.supersavedriving.user.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);
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/AppUserServiceImpl.java
New file
@@ -0,0 +1,156 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.core.shiro.ShiroKit;
import com.supersavedriving.user.core.shiro.ShiroUser;
import com.supersavedriving.user.core.util.JwtTokenUtil;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.dao.AppUserMapper;
import com.supersavedriving.user.modular.system.model.AppUser;
import com.supersavedriving.user.modular.system.service.IAppUserService;
import com.supersavedriving.user.modular.system.util.RedisUtil;
import com.supersavedriving.user.modular.system.util.ResultUtil;
import com.supersavedriving.user.modular.system.util.weChat.WXCore;
import com.supersavedriving.user.modular.system.util.weChat.WeChatUtil;
import com.supersavedriving.user.modular.system.util.weChat.model.Code2Session;
import com.supersavedriving.user.modular.system.warpper.SignInToRegister;
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.stereotype.Service;
import java.util.Date;
/**
 * 用户
 */
@Service
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements IAppUserService {
    @Autowired
    private WeChatUtil weChatUtil;
    @Autowired
    private RedisUtil redisUtil;
    private final String salt = "s5d1";
    @Override
    public ResultUtil<String> appUserLogin(String jscode) throws Exception {
        Code2Session code2Session = weChatUtil.code2Session(jscode);
        if(code2Session.getErrcode() != 0){
            return ResultUtil.error(code2Session.getErrmsg());
        }
        String openid = code2Session.getOpenid();
        AppUser appUser = this.selectOne(new EntityWrapper<AppUser>().eq("openid", openid).ne("status", 3));
        if(null == appUser){
            return ResultUtil.error("无效的账号");
        }
        if(appUser.getStatus() == 2){
            return ResultUtil.error("账号被冻结");
        }
        String token = getToken(appUser);
        if(ToolUtil.isEmpty(token)){
            return ResultUtil.error("获取身份凭证失败");
        }
        return ResultUtil.success(token);
    }
    /**
     * 获取身份凭证
     * @return
     */
    public String getToken(AppUser appUser){
        //封装请求账号密码为shiro可验证的token
        String phone = appUser.getPhone();
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(phone, phone.toCharArray());
        String credentials = ShiroKit.md5(phone, salt);
        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) {
            String token = JwtTokenUtil.generateToken(phone);
            String key = token;
            if(token.length() > 16){
                key = token.substring(token.length() - 16);
            }
            redisUtil.setStrValue(key, appUser.getId().toString(), 7 * 24 * 60 * 60);
            return token;
        }
        return null;
    }
    /**
     * 微信授权注册登录
     * @param signInToRegister
     * @return
     * @throws Exception
     */
    @Override
    public ResultUtil signInToRegister(SignInToRegister signInToRegister) throws Exception {
        if(ToolUtil.isEmpty(signInToRegister.getJscode())){
            return ResultUtil.paranErr("jscode");
        }
        if(ToolUtil.isEmpty(signInToRegister.getEncryptedDataPhone())){
            return ResultUtil.paranErr("encryptedDataPhone");
        }
        if(ToolUtil.isEmpty(signInToRegister.getIvPhone())){
            return ResultUtil.paranErr("ivPhone");
        }
        Code2Session code2Session = weChatUtil.code2Session(signInToRegister.getJscode());
        if(code2Session.getErrcode() != 0){
            return ResultUtil.error(code2Session.getErrmsg());
        }
        String openid = code2Session.getOpenid();
        String session_key = code2Session.getSession_key();
        String decrypt = WXCore.decrypt(signInToRegister.getEncryptedDataPhone(), session_key, signInToRegister.getIvPhone());
        if(ToolUtil.isEmpty(decrypt)){
            return ResultUtil.error("获取手机号失败");
        }
        JSONObject phone = JSON.parseObject(decrypt);
        String purePhoneNumber = phone.getString("purePhoneNumber");
        AppUser appUser = this.selectOne(new EntityWrapper<AppUser>().eq("phone", purePhoneNumber).ne("status", 3));
        if(null == appUser){
            appUser = new AppUser();
            appUser.setNickname("亲爱的用户");
            appUser.setPhone(purePhoneNumber);
            appUser.setOpenid(openid);
            appUser.setUnionid(code2Session.getUnionid());
            appUser.setAccountBalance(0D);
            appUser.setStatus(1);
            appUser.setCreateTime(new Date());
            appUser.setIsException(1);
            appUser.setInviterId(signInToRegister.getInviterId());
            appUser.setInviterType(signInToRegister.getInviterType());
            this.insert(appUser);
        }
        if(appUser.getStatus() == 2){
            return ResultUtil.error("账号被冻结");
        }
        String token = getToken(appUser);
        if(ToolUtil.isEmpty(token)){
            return ResultUtil.error("获取身份凭证失败");
        }
        return ResultUtil.success(token);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DeptServiceImpl.java
New file
@@ -0,0 +1,47 @@
package com.supersavedriving.user.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.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.modular.system.dao.DeptMapper;
import com.supersavedriving.user.modular.system.model.Dept;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/DictServiceImpl.java
New file
@@ -0,0 +1,100 @@
package com.supersavedriving.user.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.supersavedriving.user.core.common.exception.BizExceptionEnum;
import com.supersavedriving.user.core.exception.GunsException;
import com.supersavedriving.user.modular.system.dao.DictMapper;
import com.supersavedriving.user.modular.system.model.Dict;
import com.supersavedriving.user.modular.system.service.IDictService;
import com.supersavedriving.user.core.common.constant.factory.MutiStrFactory;
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 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 = MutiStrFactory.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(MutiStrFactory.MUTI_STR_CODE);
            String name = item.get(MutiStrFactory.MUTI_STR_NAME);
            String num = item.get(MutiStrFactory.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/HtmlServiceImpl.java
New file
@@ -0,0 +1,16 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.modular.system.dao.HtmlMapper;
import com.supersavedriving.user.modular.system.model.Html;
import com.supersavedriving.user.modular.system.service.IHtmlService;
import org.springframework.stereotype.Service;
/**
 * TODO 协议
 * @author 39373
 * @date 2023/2/26 17:31
 */
@Service
public class HtmlServiceImpl extends ServiceImpl<HtmlMapper, Html> implements IHtmlService {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/LoginLogServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.modular.system.dao.LoginLogMapper;
import com.supersavedriving.user.modular.system.model.LoginLog;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/MenuServiceImpl.java
New file
@@ -0,0 +1,90 @@
package com.supersavedriving.user.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.supersavedriving.user.core.node.MenuNode;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.modular.system.dao.MenuMapper;
import com.supersavedriving.user.modular.system.model.Menu;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/NoticeServiceImpl.java
New file
@@ -0,0 +1,27 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.modular.system.dao.NoticeMapper;
import com.supersavedriving.user.modular.system.model.Notice;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/OperationLogServiceImpl.java
New file
@@ -0,0 +1,28 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.modular.system.dao.OperationLogMapper;
import com.supersavedriving.user.modular.system.model.OperationLog;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/RelationServiceImpl.java
New file
@@ -0,0 +1,20 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.modular.system.dao.RelationMapper;
import com.supersavedriving.user.modular.system.model.Relation;
import com.supersavedriving.user.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 {
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/RoleServiceImpl.java
New file
@@ -0,0 +1,73 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.core.node.ZTreeNode;
import com.supersavedriving.user.core.util.Convert;
import com.supersavedriving.user.modular.system.dao.RelationMapper;
import com.supersavedriving.user.modular.system.dao.RoleMapper;
import com.supersavedriving.user.modular.system.model.Relation;
import com.supersavedriving.user.modular.system.model.Role;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/service/impl/UserServiceImpl.java
New file
@@ -0,0 +1,48 @@
package com.supersavedriving.user.modular.system.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.supersavedriving.user.core.datascope.DataScope;
import com.supersavedriving.user.modular.system.dao.UserMapper;
import com.supersavedriving.user.modular.system.model.User;
import com.supersavedriving.user.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ManagerUser.java
New file
@@ -0,0 +1,97 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ReqAddManager.java
New file
@@ -0,0 +1,76 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/ReqEditManager.java
New file
@@ -0,0 +1,60 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/transfer/UserDto.java
New file
@@ -0,0 +1,153 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ALiApiUtil.java
New file
@@ -0,0 +1,51 @@
package com.supersavedriving.user.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 阿里云API接口工具类
 */
@Component
public class ALiApiUtil {
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 身份认证接口
     * @param name  姓名
     * @param code  身份证号
     * @return
     */
    public boolean authentication(String name, String code){
        String url = "https://safrvcert.market.alicloudapi.com/safrv_2meta_id_name/";
        Map<String, String> header = new HashMap<>();
        header.put("Authorization", "APPCODE b7d32437d08149099457dcb50fb57df2");
        Map<String, Object> param = new HashMap<>();
        param.put("__userId", "1732960796168165");
        param.put("verifyKey", "IVO4js5kValcdt");
        param.put("userName", name);
        param.put("identifyNum", code);
        String get = httpClientUtil.pushHttpRequset("GET", url, param, header, "form");
        JSONObject jsonObject = JSON.parseObject(get);
        if(jsonObject.getIntValue("code") == 200){
            JSONObject value = jsonObject.getJSONObject("value");
            if(value.getIntValue("bizCode") == 0){
                return true;
            }else{
                return false;
            }
        }else{
            System.err.println(jsonObject.getString("message"));
        }
        return false;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ALiSendSms.java
New file
@@ -0,0 +1,123 @@
package com.supersavedriving.user.modular.system.util;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.google.gson.Gson;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
 * 阿里云短信工具类
 */
@Component
public class ALiSendSms {
    // 设置鉴权参数,初始化客户端
    private DefaultProfile profile = DefaultProfile.getProfile(
            "cn-hangzhou",// 地域ID
            "LTAI4G9Zez9H4B36vakPXGy4",// 您的AccessKey ID
            "BOVPUeZndKVbrPOq6Ef5j6oiydB3XZ");// 您的AccessKey Secret
    private IAcsClient client = new DefaultAcsClient(profile);
    private static void log_print(String functionName, Object result) {
        Gson gson = new Gson();
        System.out.println("-------------------------------" + functionName + "-------------------------------");
        System.out.println(gson.toJson(result));
    }
    /**
     * 添加短信模板
     */
    public String addSmsTemplate() throws ClientException {
        CommonRequest addSmsTemplateRequest = new CommonRequest();
        addSmsTemplateRequest.setSysDomain("dysmsapi.aliyuncs.com");
        addSmsTemplateRequest.setSysAction("AddSmsTemplate");
        addSmsTemplateRequest.setSysVersion("2017-05-25");
        // 短信类型。0:验证码;1:短信通知;2:推广短信;3:国际/港澳台消息
        addSmsTemplateRequest.putQueryParameter("TemplateType", "0");
        // 模板名称,长度为1~30个字符
        addSmsTemplateRequest.putQueryParameter("TemplateName", "测试短信模板");
        // 模板内容,长度为1~500个字符
        addSmsTemplateRequest.putQueryParameter("TemplateContent", "您正在申请手机注册,验证码为:${code},5分钟内有效!");
        // 短信模板申请说明
        addSmsTemplateRequest.putQueryParameter("Remark", "测试");
        CommonResponse addSmsTemplateResponse = client.getCommonResponse(addSmsTemplateRequest);
        String data = addSmsTemplateResponse.getData();
        // 消除返回文本中的反转义字符
        String sData = data.replaceAll("'\'", "");
        log_print("addSmsTemplate", sData);
        Gson gson = new Gson();
        // 将字符串转换为Map类型,取TemplateCode字段值
        Map map = gson.fromJson(sData, Map.class);
        Object templateCode = map.get("TemplateCode");
        return templateCode.toString();
    }
    /**
     * 发送短信
     */
    public String sendSms(String phone, String templateCode, String json) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        // 接收短信的手机号码
        request.putQueryParameter("PhoneNumbers", phone);
        // 短信签名名称。请在控制台签名管理页面签名名称一列查看(必须是已添加、并通过审核的短信签名)。
        request.putQueryParameter("SignName", "OK出行");
        // 短信模板ID
        request.putQueryParameter("TemplateCode", templateCode);
        // 短信模板变量对应的实际值,JSON格式。
        request.putQueryParameter("TemplateParam", json);
        CommonResponse commonResponse = client.getCommonResponse(request);
        String data = commonResponse.getData();
        String sData = data.replaceAll("'\'", "");
        log_print("sendSms", sData);
        return sData;
    }
    /**
     * 查询发送详情
     */
    private void querySendDetails(String bizId) throws ClientException {
        CommonRequest request = new CommonRequest();
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("QuerySendDetails");
        // 接收短信的手机号码
        request.putQueryParameter("PhoneNumber", "156xxxxxxxx");
        // 短信发送日期,支持查询最近30天的记录。格式为yyyyMMdd,例如20191010。
        request.putQueryParameter("SendDate", "20191010");
        // 分页记录数量
        request.putQueryParameter("PageSize", "10");
        // 分页当前页码
        request.putQueryParameter("CurrentPage", "1");
        // 发送回执ID,即发送流水号。
        request.putQueryParameter("BizId", bizId);
        CommonResponse response = client.getCommonResponse(request);
        log_print("querySendDetails", response.getData());
    }
    public static void main(String[] args) {
        ALiSendSms sendSmsDemo = new ALiSendSms();
        try {
            // 创建短信模板
            String templateCode = sendSmsDemo.addSmsTemplate();
            // 使用刚创建的短信模板发送短信
            String sData = sendSmsDemo.sendSms("156xxxxxxxx", templateCode, "{\"code\":\"8888\"}");
            Gson gson = new Gson();
            Map map = gson.fromJson(sData, Map.class);
            String bizId = map.get("BizId").toString();
            // 根据短信发送流水号查询短信发送情况
            sendSmsDemo.querySendDetails(bizId);
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ChinaMobileUtil.java
New file
@@ -0,0 +1,133 @@
package com.supersavedriving.user.modular.system.util;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.user.core.util.MD5Util;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 中国移动工具类
 */
@Component
public class ChinaMobileUtil {
    private String APIKey = "zj42494b1bdd416b9762229af6b5cbbd";
    private String SecretKey = "30323561316534653735613230316339";
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 绑定小号
     * @param phoneA
     * @param phoneB
     * @param areaCode
     * @return
     * @throws Exception
     */
    public Map<String, String> midAxbBindSend(String phoneA, String phoneB, Integer areaCode) throws Exception{
        //组装请求对象-具体描述见开发文档-订单小号-AXB接口规范部分内容
        Map<String, Object> request = new HashMap<>();
        request.put("APPID", APIKey);
        request.put("bindtype", "AXB");
        request.put("requestId", UUIDUtil.getRandomCode(16));
        request.put("record", "0");
        //用户号码,必填,格式遵循国际电信联盟定义的E.164标准
        request.put("telA", "86" + phoneA);
        //用户号码B,必填,格式遵循国际电信联盟定义的E.164标准
        request.put("telB", "86" + phoneB);
        //需要选择的小号所属区号,当telX不写时必填,例如:杭州(571)
        request.put("areaCode", 571);
        //订单小号,非必填,当指定小号绑定时填写,格式遵循国际电信联盟定义的E.164标准
//        request.setTelX("8618867110000");
        //绑定关系过期失效时间,秒,取值必须大于0且最大值不超过4294967296
        request.put("expiration", Integer.valueOf(7 * 24 * 60 * 60));
        Map<String, String> header = new HashMap<String, String>(3);
        header.put("Authorization", "Basic " + new String(Base64.encodeBase64((APIKey + ":" + SecretKey).getBytes())));
        header.put("Content-Type", "application/json;charset=utf-8");
        String post = httpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/binding", request, header, "json");
        Map<String, String> map1 = new HashMap<>();
        if(post.indexOf("0000") != -1){
            JSONObject jsonObject = JSONObject.parseObject(post);
            if(jsonObject.getString("code").equals("0000")){
                map1.put("code", "200");
                map1.put("msg", jsonObject.getString("message"));
                map1.put("telX", jsonObject.getString("x_no").substring(2));
                map1.put("bindId", jsonObject.getString("bindId"));
            }else{
                map1.put("code", jsonObject.getString("code"));
                map1.put("msg", jsonObject.getString("message"));
            }
        }else{
            map1.put("code", "-1");
            map1.put("msg", post);
        }
        return map1;
    }
    /**
     * 解绑小号关系
     * @param bindId    绑定关系id
     * @return
     * @throws Exception
     */
    public Map<String, String> midAxbUnBindSend(String bindId) throws Exception{
        //组装请求对象-具体描述见开发文档-订单小号-AXB接口规范部分内容
        Map<String, Object> request = new HashMap<>();
        //绑定关系ID
        request.put("APPID", APIKey);
        request.put("bindId", bindId);
        Map<String, String> header = new HashMap<String, String>(3);
        header.put("Authorization", "Basic " + new String(Base64.encodeBase64((APIKey + ":" + SecretKey).getBytes())));
        header.put("Content-Type", "application/json;charset=utf-8");
        String post = httpClientUtil.pushHttpRequset("POST", "https://ct.open.10086.cn/ordernumber/v1/unbinding", request, header, "json");
        Map<String, String> map1 = new HashMap<>();
        if(post.indexOf("0000") != -1){
            JSONObject jsonObject = JSONObject.parseObject(post);
            if(jsonObject.getString("code").equals("0000")){
                map1.put("code", "200");
                map1.put("msg", jsonObject.getString("message"));
            }else{
                map1.put("code", jsonObject.getString("code"));
                map1.put("msg", jsonObject.getString("message"));
            }
        }else{
            map1.put("code", "-1");
            map1.put("msg", post);
        }
        return map1;
    }
    public Map<String, String> HeaderUtils(String APIKey, String SecretKey) throws Exception{
        Map<String, String> header = new HashMap<>();
        long time = System.currentTimeMillis();
        String signStr = MD5Util.encrypt(APIKey + SecretKey + time);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("apiKey", APIKey);
        jsonObject.put("time", time);
        jsonObject.put("sign", signStr);
        Base64 base64 = new Base64();
        String s = base64.encodeToString(jsonObject.toJSONString().getBytes("UTF-8"));
        header.put("header", s);
        jsonObject = new JSONObject();
        jsonObject.put("platformId", "");
        jsonObject.put("secret", "");
        s = base64.encodeToString(jsonObject.toJSONString().getBytes("UTF-8"));
        header.put("accessCode", s);
        return header;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/DateUtil.java
New file
@@ -0,0 +1,135 @@
package com.supersavedriving.user.modular.system.util;
import com.supersavedriving.user.core.util.ToolUtil;
import org.springframework.stereotype.Component;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
 * 日期处理工具类
 */
@Component
public class DateUtil {
    /**
     * 获取给定日期天的开始时间点或结束时间点
     * @param time  日期
     * @param type  时间点类型start一天的开始时间点,end一天的结束时间点
     * @return
     */
    public Date getStartOrEndDate(Date time, String type){
        if(ToolUtil.isEmpty(time) || ToolUtil.isEmpty(type)){
            return null;
        }
        int hourOfDay = "start".equals(type) ? 0 : 23;
        int minute = "start".equals(type) ? 0 : 59;
        int second = "start".equals(type) ? 0 : 59;
        int millisecond = "start".equals(type) ? 0 : 999;
        Calendar s = Calendar.getInstance();
        s.setTime(time);
        s.set(s.get(Calendar.YEAR), s.get(Calendar.MONTH), s.get(Calendar.DAY_OF_MONTH), hourOfDay, minute, second);
        s.set(Calendar.MILLISECOND, millisecond);
        return s.getTime();
    }
    /**
     * 获取给定日期天的起始时间和结束时间
     * @param time
     * @return
     */
    public Map<String, Date> getStartAndEndDate(Date time){
        if(ToolUtil.isEmpty(time)){
            return null;
        }
        Map<String, Date> map = new HashMap<>();
        map.put("startTime", getStartOrEndDate(time, "start"));
        map.put("endTime", getStartOrEndDate(time, "end"));
        return map;
    }
    /**
     * 获取格式化的字符串日期返回日期天的起始时间和结束时间
     * @param time  yyyy-MM-dd DD:mm:ss/yyyy-MM-dd
     * @return
     */
    public Map<String, Date> getStartAndEndDate(String time){
        if(ToolUtil.isEmpty(time)){
            return null;
        }
        int index = time.indexOf(" ");
        String pattern = "yyyy-MM-dd DD:mm:ss";
        if(index == -1){
            pattern = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date = null;
        try {
            date = sdf.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return getStartAndEndDate(date);
    }
    /**
     * 获取格式化的字符串区间日期返回区间日期天的起始时间和结束时间
     * @param time      yyyy-MM-dd DD:mm:ss - yyyy-MM-dd DD:mm:ss/yyyy-MM-dd - yyyy-MM-dd
     * @param split     区间时间的分隔符
     * @return
     */
    public List<Date> getStartAndEndDate(String time, String split){
        if(ToolUtil.isEmpty(time) || ToolUtil.isEmpty(split)){
            return null;
        }
        List<Date> list = new ArrayList<>();
        String[] split1 = time.split(split);
        int index = split1[0].indexOf(" ");
        String pattern = "yyyy-MM-dd DD:mm:ss";
        if(index == -1){
            pattern = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        Date date1 = null;
        Date date2 = null;
        try {
            date1 = sdf.parse(split1[0]);
            date2 = sdf.parse(split1[1]);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        list.add(getStartOrEndDate(date1, "start"));
        list.add(getStartOrEndDate(date2, "end"));
        return list;
    }
    /**
     * 获取月初和月末日期
     * @param date
     * @return
     */
    public Map<String, Date> getMonthStartAndEnd(Date date){
        Calendar s = Calendar.getInstance();
        s.setTime(date);
        s.set(Calendar.DAY_OF_MONTH, 1);
        Calendar e = Calendar.getInstance();
        e.setTime(date);
        e.set(Calendar.DAY_OF_MONTH, e.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date start = this.getStartOrEndDate(s.getTime(), "start");
        Date end = this.getStartOrEndDate(e.getTime(), "end");
        Map<String, Date> map = new HashMap<>();
        map.put("startTime", start);
        map.put("endTime", end);
        return map;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/GDFalconUtil.java
New file
@@ -0,0 +1,226 @@
package com.supersavedriving.user.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.Map;
/**
 * 高德猎鹰服务
 */
@Component
public class GDFalconUtil implements ApplicationRunner {
    private String key = "e17d799b2506d05faf7f88320a266803";
    @Autowired
    private RestTemplate restTemplate;
    private static String serverId = null;
    public String getServerId() {
        return serverId;
    }
    /**
     * 服务启动后执行的代码
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        this.init();
    }
    /**
     * 初始化创建服务
     */
    public void init(){
        if(serverId == null){
            JSONArray jsonArray = this.selectServer();
            if(null == jsonArray){
                serverId = this.createServer("server");
            }else{
                serverId = jsonArray.getJSONObject(0).getString("sid");
            }
        }
    }
    /**
     * 创建新的服务
     * @return
     */
    public String createServer(String name){
        String url = "https://tsapi.amap.com/v1/track/service/add";
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("key", key);
        params.add("name", name);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = restTemplate.postForObject(url, requestEntity , String.class);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.getIntValue("errcode") == 10000){
            JSONObject data = jsonObject.getJSONObject("data");
            if(null != data){
                return data.getString("sid");
            }
        }
        return null;
    }
    /**
     * 查询服务
     * @return
     */
    private JSONArray selectServer(){
        String url = "https://tsapi.amap.com/v1/track/service/list?key=" + key;
        String forObject = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSON.parseObject(forObject);
        if(jsonObject.getIntValue("errcode") == 10000){
            JSONObject data = jsonObject.getJSONObject("data");
            if(null != data){
                return data.getJSONArray("results");
            }
        }
        return null;
    }
    /**
     * 创建终端数据
     * @param name
     * @return
     */
    public String createTerminal(String name){
        String tid = this.selectTerminal(name);
        if(tid != null){
            return tid;
        }
        String url = "https://tsapi.amap.com/v1/track/terminal/add";
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("key", key);
        params.add("sid", serverId);
        params.add("name", name);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = restTemplate.postForObject(url, requestEntity , String.class);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.getIntValue("errcode") == 10000){
            JSONObject data = jsonObject.getJSONObject("data");
            return data.getString("tid");
        }
        System.err.println(jsonObject.getString("errmsg"));
        return null;
    }
    /**
     * 查询终端
     * @param name
     * @return
     */
    public String selectTerminal(String name){
        String url = "https://tsapi.amap.com/v1/track/terminal/list?key=" + key + "&name=" + name;
        String forObject = restTemplate.getForObject(url, String.class);
        JSONObject jsonObject = JSON.parseObject(forObject);
        if(jsonObject.getIntValue("errcode") == 10000){
            JSONObject data = jsonObject.getJSONObject("data");
            int count = 0;
            if(null != data){
                count = data.getIntValue("count");
            }
            if(count > 0){
                JSONObject results = data.getJSONArray("results").getJSONObject(0);
                return results.getString("tid");
            }else{
                return this.createTerminal(name);
            }
        }
        return null;
    }
    /**
     * 创建轨迹
     * @param tid   终端id
     * @return
     */
    public String createTrack(String tid){
        String url = "https://tsapi.amap.com/v1/track/trace/add";
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("key", key);
        params.add("sid", serverId);
        params.add("tid", tid);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = restTemplate.postForObject(url, requestEntity , String.class);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.getIntValue("errcode") == 10000){
            return jsonObject.getString("data");
        }
        System.err.println(jsonObject.getString("errmsg"));
        return null;
    }
    /**
     * 删除轨迹
     * @param tid       终端id
     * @param trid      轨迹id
     */
    public void deleteTrack(String tid, String trid){
        String url = "https://tsapi.amap.com/v1/track/trace/delete";
        //调用推送
        HttpHeaders headers = new HttpHeaders();
        // 以表单的方式提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //将请求头部和参数合成一个请求
        MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
        params.add("key", key);
        params.add("sid", serverId);
        params.add("tid", tid);
        params.add("trid", trid);
        HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(params, headers);
        String s = restTemplate.postForObject(url, requestEntity , String.class);
        JSONObject jsonObject = JSON.parseObject(s);
        if(jsonObject.getIntValue("errcode") != 10000){
            System.err.println(jsonObject.getString("errmsg"));
        }
    }
//
//    public Map<String, Object> queryTrsearch(){
//
//    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/GeodesyUtil.java
New file
@@ -0,0 +1,75 @@
package com.supersavedriving.user.modular.system.util;
import com.supersavedriving.user.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);
//            System.out.println("Sphere坐标系计算结果:"+Sphere + "米");
//            System.out.println("WGS84坐标系计算结果:"+WGS84 + "米");
//            System.out.println("GRS80坐标系计算结果:"+GRS80 + "米");
//            System.out.println("GRS67坐标系计算结果:"+GRS67 + "米");
//            System.out.println("ANS坐标系计算结果:"+ANS + "米");
//            System.out.println("WGS72坐标系计算结果:"+WGS72 + "米");
//            System.out.println("Clarke1858坐标系计算结果:"+Clarke1858 + "米");
//            System.out.println("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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/JGPushUtil.java
New file
@@ -0,0 +1,92 @@
package com.supersavedriving.user.modular.system.util;
import cn.jiguang.common.ClientConfig;
import cn.jiguang.common.resp.APIConnectionException;
import cn.jiguang.common.resp.APIRequestException;
import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.Notification;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
 * 极光推送工具类
 */
@Component
public class JGPushUtil {
    @Value("${jiguang.appKey-driver}")
    private String appKeyDriver;
    @Value("${jiguang.masterSecret-driver}")
    private String masterSecretDriver;
    @Value("${jiguang.appKey-dispatch}")
    private String appKeyDispatch;
    @Value("${jiguang.masterSecret-dispatch}")
    private String masterSecretDispatch;
    private PushPayload buildPushObject_all_all_alert(String content, String...tags) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())//设置推送平台为全部平台
                .setAudience(Audience.alias(tags))//通过别名的方式发送(用户owner_id,员工user_id)
                .setNotification(Notification.alert(content))
                .build();
    }
    private PushPayload buildPushObject_all_all_alert(String title, String content, Map<String, String> map, String...tags) {
        return PushPayload.newBuilder()
                .setPlatform(Platform.all())//设置推送平台为全部平台
                .setAudience(Audience.alias(tags))//通过别名的方式发送(用户owner_id,员工user_id)
                .setNotification(Notification.android(content, title, map))
                .setNotification(Notification.ios(content, map))
                .setNotification(Notification.winphone(content, map))
                .build();
    }
    /**
     * 推送
     * @param tags
     * @param content
     */
    public void push(Integer type, String content, String...tags){
        String masterSecret = (type == 1 ? masterSecretDriver : masterSecretDispatch);
        String appKey = (type == 1 ? appKeyDriver : appKeyDispatch);
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
        PushPayload payload = this.buildPushObject_all_all_alert(content, tags);
        try {
            PushResult result = jpushClient.sendPush(payload);
            System.err.println(result.statusCode);
        } catch (APIConnectionException e) {
            e.printStackTrace();
        } catch (APIRequestException e) {
            e.printStackTrace();
        }
    }
    public void push(Integer type, String content, String title, Map<String, String> map, String...tags){
        String masterSecret = (type == 1 ? masterSecretDriver : masterSecretDispatch);
        String appKey = (type == 1 ? appKeyDriver : appKeyDispatch);
        JPushClient jpushClient = new JPushClient(masterSecret, appKey, null, ClientConfig.getInstance());
        PushPayload payload = this.buildPushObject_all_all_alert(title, content, map, tags);
        try {
            PushResult result = jpushClient.sendPush(payload);
            System.err.println(result.statusCode);
        } catch (APIConnectionException e) {
            e.printStackTrace();
        } catch (APIRequestException e) {
            e.printStackTrace();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/JuHeUtil.java
New file
@@ -0,0 +1,75 @@
package com.supersavedriving.user.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
 * 聚合数据工具类
 */
@Component
public class JuHeUtil {
    @Value("${juhe.appKey}")
    private String key;
    @Autowired
    private HttpClientUtil httpClientUtil;
    /**
     * 身份证号码实名认证
     * @param name
     * @param idcard
     * @return
     */
    public boolean idcard(String name, String idcard){
        Map<String, Object> map = new HashMap<>();
        map.put("key", key);
        map.put("idcard", idcard);
        map.put("realname", name);
        String content = httpClientUtil.pushHttpRequset("GET", "http://op.juhe.cn/idcard/query", map, new HashMap<>(), "form");
        System.err.println(content);
        JSONObject jsonObject = JSON.parseObject(content);
        if(jsonObject.getIntValue("error_code") == 0){
            int res = jsonObject.getJSONObject("result").getIntValue("res");
            return res == 1 ? true : false;
        }
        return false;
    }
    /**
     * 根据银行卡号获取银行数据
     * @param code
     * @return
     */
    public Map<String, String> queryBank(String code){
        String url = "http://apis.juhe.cn/interbank/query?key=" + key + "&bankcard=" + code;
        String get = httpClientUtil.pushHttpRequset("GET", url, null, null, "form");
        JSONObject jsonObject = JSON.parseObject(get);
        Map<String, String> map = new HashMap<>();
        if(jsonObject.getIntValue("error_code") == 0){
            JSONObject result = jsonObject.getJSONObject("result");
            JSONObject data = result.getJSONObject("data");
            JSONObject record = data.getJSONArray("record").getJSONObject(0);
            String province = record.getString("province");
            String city = record.getString("city");
            String district = record.getString("district");
            String address = record.getString("addr");
            map.put("msg", "success");
            map.put("address", province + city + district);
            map.put("bank_name", record.getString("lname"));
            map.put("bank", record.getString("bank"));
            map.put("bank_code", record.getString("bankcode"));//联行号
        }else{
            map.put("msg", jsonObject.getString("reason"));
        }
        return map;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/MD5AndKL.java
New file
@@ -0,0 +1,112 @@
package com.supersavedriving.user.modular.system.util;
import java.security.MessageDigest;
public class MD5AndKL {
    /**
     * 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[]) {
        System.out.println("MD5后再加密:" + KL(MD5("123456")));
        System.out.println(MD5("123456"));
        // System.out.println("加密:" + KL(MD5("123456")));
        // s = KL(s);
        // System.out.println("解密:" + KL("81dc9bdb52d04dc20036dbd8313ed055"));
        // System.out.println("解密:" + JM(KL(s)));
        // System.out.println("解密为MD5后的:" + KL(KL(MD5(s))));
        // System.out.println(JM("5d62957bb57d3e49dcf48a0df064be4c"));
        // System.out.println(MD5AndKL.KL(MD5AndKL.MD5("admin"+"87654321")));
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/PayMoneyUtil.java
New file
@@ -0,0 +1,809 @@
package com.supersavedriving.user.modular.system.util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import org.apache.commons.collections.map.HashedMap;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.math.BigDecimal;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.*;
/**
 * 第三方支付工具类
 */
@Component
public class PayMoneyUtil {
    @Value("${alipay.appid}")
    private String aliAppid;//支付宝appid
    @Value("${alipay.appPrivateKey}")
    private String appPrivateKey;//支付宝开发者应用私钥
    @Value("${alipay.alipayPublicKey}")
    private String alipayPublicKey;//支付宝应用公钥
    @Value("${alipay.alipay_public_key}")
    private String alipay_public_key;//支付宝支付公钥
    @Value("${wx.appid}")
    private String appid;//微信appid
    @Value("${wx.mchId}")
    private String mchId;//微信商户号
    @Value("${wx.key}")
    private String key;//微信商户号
    @Value("${callbackPath}")
    private String callbackPath;//支付回调网关地址
    @Autowired
    private HttpClientUtil httpClientUtil;
    private Map<String, JSONObject> order = new HashMap<>();//存储支付订单用于主动查询支付结果
    /**
     * 支付宝支付
     */
    public ResultUtil alipay(String body, String subject, String outTradeNo, String amount, String notifyUrl){
        //实例化客户端
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipayPublicKey, "RSA2");
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
        model.setBody(body);//对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。
        model.setSubject(subject);//商品的标题/交易标题/订单标题/订单关键字等。
        model.setOutTradeNo(outTradeNo);//商户网站唯一订单号
        model.setTimeoutExpress("30m");
        model.setTotalAmount(amount);//付款金额
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(callbackPath + notifyUrl);
        try {
            //这里和普通的接口调用不同,使用的是sdkExecute
            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
            Map<String, String> map = new HashMap<>();
            map.put("orderString", response.getBody());
            System.out.println(map);//就是orderString 可以直接给客户端请求,无需再做处理。
            return ResultUtil.success(map);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 支付宝扫码支付下单
     * @param body
     * @param subject
     * @param outTradeNo
     * @param amount
     * @param notifyUrl
     * @return
     */
    public ResultUtil aliScanCodePay(String body, String subject, String outTradeNo, String amount, String notifyUrl){
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey, "json", "UTF-8", alipay_public_key, "RSA2"); //获得初始化的AlipayClient
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();//创建API对应的request类
        request.setBizContent("{" +
                "    \"out_trade_no\":\"" + outTradeNo + "\"," +//商户订单号
                "    \"total_amount\":\"" + 1 + "\"," +
                "    \"subject\":\"" + subject + "\"," +
                "    \"notify_url\":\"" + callbackPath + notifyUrl + "\"," +
                "    \"body\":\"" + body + "\"," +
                "    \"store_id\":\"NJ_001\"," +
                "    \"timeout_express\":\"90m\"}");//订单允许的最晚付款时间
        AlipayTradePrecreateResponse response = null;
        try {
            response = alipayClient.execute(request);
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        JSONObject alipay_trade_precreate_response = JSON.parseObject(response.getBody()).getJSONObject("alipay_trade_precreate_response");
        System.err.print(alipay_trade_precreate_response.getString("qr_code"));
        return ResultUtil.success(alipay_trade_precreate_response.getString("qr_code"));
    }
    /**
     * 支付成功后的回调处理逻辑
     * @param request
     */
    public Map<String, String> alipayCallback(HttpServletRequest request){
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
        //boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type)
        try {
            boolean flag = AlipaySignature.rsaCheckV1(params, alipayPublicKey, "UTF-8","RSA2");
            if(flag){
                Map<String, String> map = new HashMap<>();
                String out_trade_no = params.get("out_trade_no");
                String subject = params.get("subject");
                String total_amount = params.get("total_amount");
                String trade_no = params.get("trade_no");
                map.put("out_trade_no", out_trade_no);//商家订单号
                map.put("subject", subject);
                map.put("total_amount", total_amount);
                map.put("trade_no", trade_no);//支付宝交易号
                return map;
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 支付宝查询订单支付状态
     * @param out_trade_no
     * @return
     * @throws Exception
     */
    public ResultUtil queryALIOrder(String out_trade_no) throws Exception{
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",aliAppid, appPrivateKey,"json","UTF-8", alipay_public_key,"RSA2");
        AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
        request.setBizContent("{" +
                "\"out_trade_no\":" + out_trade_no +
                "  }");
        AlipayTradeQueryResponse response = alipayClient.execute(request);
        if(response.isSuccess()){
            String tradeStatus = response.getTradeStatus();//交易状态:WAIT_BUYER_PAY(交易创建,等待买家付款)、TRADE_CLOSED(未付款交易超时关闭,或支付完成后全额退款)、TRADE_SUCCESS(交易支付成功)、TRADE_FINISHED(交易结束,不可退款)
            return ResultUtil.success(tradeStatus);
        } else {
            return ResultUtil.error(response.getMsg());
        }
    }
    /**
     * 微信统一下单
     * @param body          商品描述
     * @param attach        附加数据
     * @param out_trade_no  商户订单号
     * @param total_fee     标价金额
     * @param notify_url    通知地址
     * @param tradeType     交易类型
     * @return
     */
    public ResultUtil weixinpay(String body, String attach, String out_trade_no, String total_fee, String notify_url, String tradeType) throws Exception{
        int i = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue();
        String hostAddress = null;
        try {
            hostAddress = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String nonce_str = UUIDUtil.getRandomCode(16);
        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("mch_id", mchId);
        map.put("nonce_str", nonce_str);
        map.put("body", body);
        map.put("attach", attach);//存储订单id
        map.put("out_trade_no", out_trade_no);//存储的订单code
        map.put("total_fee", i);
        map.put("spbill_create_ip", hostAddress);
        map.put("notify_url", callbackPath + notify_url);
        map.put("trade_type", tradeType);
        String s = this.weixinSignature(map);
        map.put("sign", s);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_XML);
        StringBuffer xmlString = new StringBuffer();
        Set<String> strings = map.keySet();
        String[] keys = {};
        keys = strings.toArray(keys);
        Arrays.sort(keys);
        xmlString.append("<xml>");
        for(int l = 0; l < keys.length; l++){
            xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
        }
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
        try {
            map1 = this.xmlToMap(body1, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        String return_code = map1.get("return_code");
        if("SUCCESS".equals(return_code)){
            String result_code = map1.get("result_code");
            if("SUCCESS".equals(result_code)){
                String type = map1.get("trade_type");
                switch (type){
                    case "JSAPI":
                        break;
                    case "NATIVE":
                        String code_url = map1.get("code_url");
                        return ResultUtil.success(code_url);
                    case "APP":
                        String prepay_id = map1.get("prepay_id");
                        //重新进行签名后返回给前端
                        Map<String, Object> map2 = new HashMap<>();
                        map2.put("appid", appid);
                        map2.put("noncestr", nonce_str);
                        map2.put("package", "Sign=WXPay");
                        map2.put("partnerid", mchId);
                        map2.put("prepayid", prepay_id);
                        map2.put("timestamp", new Date().getTime() / 1000);
                        String s1 = this.weixinSignature(map2);
                        map2.put("sign", s1);
                        System.err.println(map2);
                        return ResultUtil.success(map2);
                }
                return null;
            }else{
                System.err.println(map1.get("err_code_des"));
                return ResultUtil.error(map1.get("err_code_des"));
            }
        }else{
            System.err.println(map1.get("return_msg") + appid + "----" + mchId);
            return ResultUtil.error(map1.get("return_msg"), new JSONObject());
        }
    }
    /**
     * 微信支付成功后的回调处理
     * @param request
     */
    public Map<String, String> weixinpayCallback(HttpServletRequest request){
        try {
            String param = this.getParam(request);
            param = param.replaceAll("<!\\[CDATA\\[","");
            param = param.replaceAll("]]>", "");
            Map<String, String> map = this.xmlToMap(param, "UTF-8");
            String return_code = map.get("return_code");
            if("SUCCESS".equals(return_code)){
                String result_code = map.get("result_code");
                if("SUCCESS".equals(result_code)){
                    Map<String, String> map1 = new HashedMap();
                    map1.put("nonce_str", map.get("nonce_str"));
                    map1.put("out_trade_no", map.get("out_trade_no").split("_")[1]);//存储的订单code
                    map1.put("attach", map.get("attach"));//存储订单id
                    map1.put("total_fee", map.get("total_fee"));
                    map1.put("transaction_id", map.get("transaction_id"));//微信支付订单号
                    String result = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
                    map1.put("result", result);
                    return map1;
                }else{
//                    System.err.println(map.get("err_code_des"));
                }
            }else{
//                System.err.println(map.get("return_msg"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 微信扫码收款
     * @param body              商品描述
     * @param attach            附加数据
     * @param nonce_str         随机字符串
     * @param out_trade_no      商户订单号
     * @param total_fee         订单金额
     * @param auth_code         授权码    扫码支付授权码,设备读取用户微信中的条码或者二维码信息(注:用户付款码条形码规则:18位纯数字,以10、11、12、13、14、15开头)
     * @return
     */
    public ResultUtil wxScanQRCodePay(String body, String attach, String nonce_str, String out_trade_no, String total_fee, String auth_code){
        int i = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue();
        String hostAddress = null;
        try {
            InetAddress address = InetAddress.getLocalHost();
            hostAddress = address.getHostAddress();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        String randomCode = null;
        try {
            randomCode = UUIDUtil.getRandomCode(10);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("mch_id", mchId);
        map.put("nonce_str", nonce_str);//存储的支付人员id,员工扫描二维码支付的时候存储的是收款员工id
        map.put("body", body);
        map.put("attach", attach);//存储的费用月份数据,员工扫描二维码支付的时候存储的是收费项id
        map.put("out_trade_no", randomCode + "_" + out_trade_no);//存储的房间id
        map.put("total_fee", i);
        map.put("spbill_create_ip", hostAddress);
        map.put("auth_code", auth_code);
        String s = this.weixinSignature(map);
        map.put("sign", s);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_XML);
        StringBuffer xmlString = new StringBuffer();
        Set<String> strings = map.keySet();
        String[] keys = {};
        keys = strings.toArray(keys);
        Arrays.sort(keys);
        xmlString.append("<xml>");
        for(int l = 0; l < keys.length; l++){
            xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
        }
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
        try {
            map1 = this.xmlToMap(body1, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        String return_code = map1.get("return_code");
        if("SUCCESS".equals(return_code)){
            String result_code = map1.get("result_code");
            if("SUCCESS".equals(result_code)){
                String type = map1.get("trade_type");
                switch (type){
                    case "JSAPI":
                        break;
                    case "NATIVE":
                        String code_url = map1.get("code_url");
                        return ResultUtil.success(code_url);
                    case "APP":
                        String prepay_id = map1.get("prepay_id");
                        //重新进行签名后返回给前端
                        Map<String, Object> map2 = new HashMap<>();
                        map2.put("appid", appid);
                        map2.put("noncestr", nonce_str);
                        map2.put("package", "Sign=WXPay");
                        map2.put("partnerid", mchId);
                        map2.put("prepayid", prepay_id);
                        map2.put("timestamp", new Date().getTime() + "");
                        String s1 = this.weixinSignature(map2);
                        map2.put("pac", "Sign=WXPay");
                        map2.put("sign", s1);
//                      System.err.println(map2);
                        return ResultUtil.success(map2);
                }
                return null;
            }else{
//                System.err.println(map1.get("err_code_des"));
                return ResultUtil.error(map1.get("err_code_des"));
            }
        }else{
//            System.err.println(map1.get("return_msg") + appid + "----" + mchId);
            return ResultUtil.error(map1.get("return_msg"), new JSONObject());
        }
    }
    /**
     * 支付宝扫码收款
     * @param data
     * @return
     */
    public Object aliScanQRCodePay(String data){
        return null;
    }
    /**
     * 微信退款申请
     * @param transaction_id    微信订单号。微信生成的订单号,在支付通知中有返回
     * @param out_refund_no     商户退款单号。商户系统内部的退款单号,商户系统内部唯一,只能是数字、大小写字母_-|*@ ,同一退款单号多次请求只退一笔。
     * @param total_fee         订单金额。订单总金额,单位为分,只能为整数
     * @param refund_fee        退款金额。退款总金额,订单总金额,单位为分,只能为整数
     * @param notify_url        退款结果通知url。异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数 如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效。
     * @return
     */
    public Map<String, String> wxRefund(String transaction_id, String out_refund_no, String total_fee, String refund_fee, String notify_url){
        int tf = new BigDecimal(total_fee).multiply(new BigDecimal("100")).intValue();
        int rf = new BigDecimal(refund_fee).multiply(new BigDecimal("100")).intValue();
        String nonce_str = UUIDUtil.getRandomCode();
        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("mch_id", mchId);
        map.put("nonce_str", nonce_str);
        map.put("transaction_id", transaction_id);
        map.put("out_refund_no", out_refund_no);
        map.put("total_fee", tf);
        map.put("refund_fee", rf);
        map.put("notify_url", callbackPath + notify_url);
        String s = this.weixinSignature(map);
        map.put("sign", s);
        String url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_XML);
        StringBuffer xmlString = new StringBuffer();
        Set<String> strings = map.keySet();
        String[] keys = {};
        keys = strings.toArray(keys);
        Arrays.sort(keys);
        xmlString.append("<xml>");
        for(int l = 0; l < keys.length; l++){
            xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
        }
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
        try {
            map1 = this.xmlToMap(body1, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        String return_code = map1.get("return_code");
        Map<String, String> map2 = new HashMap<>();
        if("SUCCESS".equals(return_code)){
            String result_code = map1.get("result_code");
            if("SUCCESS".equals(result_code)){
                map2.put("return_code", result_code);
                map2.put("refund_id", String.valueOf(map1.get("refund_id")));//微信退款订单号
                map2.put("refund_fee", String.valueOf(map1.get("refund_fee")));//退款金额
                return map2;
            }else{
                map2.put("return_code", result_code);
                map2.put("return_msg", map1.get("err_code_des"));
                return map2;
            }
        }else{
            map2.put("return_code", return_code);
            map2.put("return_msg", map1.get("return_msg"));
            return map2;
        }
    }
    /**
     * 微信退款成功后的回调处理
     * @param request
     * @return
     */
    public Map<String, String> wxRefundCallback(HttpServletRequest request){
        try {
            String param = this.getParam(request);
            param = param.replaceAll("<!\\[CDATA\\[","");
            param = param.replaceAll("]]>", "");
            Map<String, String> map = this.xmlToMap(param, "UTF-8");
            String return_code = map.get("return_code");
            if("SUCCESS".equals(return_code)){
                String req_info = map.get("req_info");//加密信息请用商户秘钥进行解密
                String s = this.wxDecrypt(req_info);
                s = s.replaceAll("<!\\[CDATA\\[","");
                s = s.replaceAll("]]>", "");
                map = this.xmlToMap(s, "UTF-8");
                Map<String, String> map1 = new HashMap<>();
                map1.put("refund_id", map.get("refund_id"));
                map1.put("out_refund_no", map.get("out_refund_no"));
                return map1;
            }else{
//                System.err.println(map.get("return_msg"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchProviderException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 支付宝退款
     * @param trade_no          支付宝交易号
     * @param refund_amount     退款金额
     * @return
     * @throws AlipayApiException
     */
    public Map<String, String> aliRefund(String trade_no, String refund_amount) throws AlipayApiException {
        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", aliAppid, appPrivateKey,"json","UTF-8", alipay_public_key,"RSA2");
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("trade_no", trade_no);
        jsonObject.put("refund_amount", refund_amount);
        request.setBizContent(jsonObject.toJSONString());
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        Map<String, String> map = new HashMap<>();
        if(response.isSuccess()){
            System.out.println("调用成功");
            String outTradeNo = response.getOutTradeNo();
            map.put("code", response.getCode());//10000
            map.put("trade_no", response.getTradeNo());//支付宝交易号
            map.put("out_trade_no", outTradeNo);//商户订单号
        } else {
            System.out.println("调用失败");
            map.put("code", response.getCode());
            map.put("msg", response.getSubMsg());
        }
        return map;
    }
    /**
     * 查询微信支付订单
     * @return
     * @throws Exception
     */
    public ResultUtil queryWXOrder() throws Exception{
        String url = "https://api.mch.weixin.qq.com/pay/orderquery";
        String nonce_str = UUIDUtil.getRandomCode(16);
        Map<String, Object> map = new HashMap<>();
        map.put("appid", appid);
        map.put("mch_id", mchId);
        map.put("transaction_id", nonce_str);//微信订单号
        map.put("nonce_str", nonce_str);//随机字符串
        String s = this.weixinSignature(map);
        map.put("sign", s);
        //设置请求头
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_XML);
        StringBuffer xmlString = new StringBuffer();
        Set<String> strings = map.keySet();
        String[] keys = {};
        keys = strings.toArray(keys);
        Arrays.sort(keys);
        xmlString.append("<xml>");
        for(int l = 0; l < keys.length; l++){
            xmlString.append("<" + keys[l] + ">" + map.get(keys[l]) + "</" + keys[l] + ">");
        }
        xmlString.append("</xml>");
        Map<String, String> map1 = null;
        String body1 = httpClientUtil.pushHttpRequsetXml(url, xmlString.toString(), new HashMap<>());
        //将结果xml解析成map
        body1 = body1.replaceAll("<!\\[CDATA\\[","");
        body1 = body1.replaceAll("]]>", "");
        try {
            map1 = this.xmlToMap(body1, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        String return_code = map1.get("return_code");
        if("SUCCESS".equals(return_code)){
            String result_code = map1.get("result_code");
            if("SUCCESS".equals(result_code)){
                String type = map1.get("trade_type");
                switch (type){
                    case "JSAPI":
                        break;
                    case "NATIVE":
                        String code_url = map1.get("code_url");
                        return ResultUtil.success(code_url);
                    case "APP":
                        String trade_state = map1.get("trade_state");
                        String time_end = map1.get("time_end");
                        Map<String, Object> map2 = new HashMap<>();
                        map2.put("trade_state", trade_state);//订单状态SUCCESS—支付成功,REFUND—转入退款,NOTPAY—未支付,CLOSED—已关闭,REVOKED—已撤销(刷卡支付),USERPAYING--用户支付中,PAYERROR--支付失败(其他原因,如银行返回失败)
                        map2.put("time_end", time_end);//订单支付时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。
                        return ResultUtil.success(map2);
                }
                return null;
            }else{
                System.err.println(map1.get("err_code_des"));
                return ResultUtil.error(map1.get("err_code_des"));
            }
        }else{
            System.err.println(map1.get("return_msg") + appid + "----" + mchId);
            return ResultUtil.error(map1.get("return_msg"), new JSONObject());
        }
    }
    /**
     * 获取请求内容
     * @param request
     * @return
     * @throws IOException
     */
    private String getParam(HttpServletRequest request) throws IOException {
        // 读取参数
        InputStream inputStream;
        StringBuilder sb = new StringBuilder();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();
        return sb.toString();
    }
    /**
     * 微信下单的签名算法
     * @param map
     * @return
     */
    private String weixinSignature(Map<String, Object> map){
        try {
            Set<Map.Entry<String, Object>> entries = map.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 + "&");
                    }
                }
            }
            sb.append("key=" + key);
            String sign = MD5AndKL.MD5Encode(sb.toString(), "UTF-8").toUpperCase(); //注:MD5签名方式
            return sign;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 微信退款成功后的解密
     * @param req_info
     * @return
     */
    private String wxDecrypt(String req_info) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException,
            InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] decode = Base64.getDecoder().decode(req_info);
        String sign = MD5AndKL.MD5Encode(key, "UTF-8").toLowerCase();
        if (Security.getProvider("BC") == null){
            Security.addProvider(new BouncyCastleProvider());
        }
        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");
        SecretKeySpec secretKeySpec = new SecretKeySpec(sign.getBytes(), "AES");
        cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
        return new String(cipher.doFinal(decode));
    }
    public static void main(String[] ages){
//        PayMoneyUtil payMoneyUtil = new PayMoneyUtil();
//        payMoneyUtil.weixinpay("测试", "123", "12.5", "");
    }
    /**
     * xml转map
     * @param xml
     * @param charset
     * @return
     * @throws UnsupportedEncodingException
     * @throws DocumentException
     */
    public static Map<String, String> xmlToMap(String xml, String charset) throws UnsupportedEncodingException, DocumentException {
        Map<String, String> respMap = new HashMap<String, String>();
        SAXReader reader = new SAXReader();
        Document doc = reader.read(new ByteArrayInputStream(xml.getBytes(charset)));
        Element root = doc.getRootElement();
        xmlToMap(root, respMap);
        return respMap;
    }
    public static Map<String, String> xmlToMap(Element tmpElement, Map<String, String> respMap){
        if (tmpElement.isTextOnly()) {
            respMap.put(tmpElement.getName(), tmpElement.getText());
            return respMap;
        }
        @SuppressWarnings("unchecked")
        Iterator<Element> eItor = tmpElement.elementIterator();
        while (eItor.hasNext()) {
            Element element = eItor.next();
            xmlToMap(element, respMap);
        }
        return respMap;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/RedisUtil.java
New file
@@ -0,0 +1,239 @@
package com.supersavedriving.user.modular.system.util;
import com.supersavedriving.user.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);
    }
    /**
     * 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");
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/ResultUtil.java
New file
@@ -0,0 +1,187 @@
package com.supersavedriving.user.modular.system.util;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
/**
 * 定义统一返回对象
 */
@ApiModel(value = "统一返回结果集")
public class ResultUtil<T> {
    public static final Integer SUCCESS = 10000;
    public static final Integer PARAM_ERROR = 10010;
    public static final Integer SYSTEM_INFO = 10020;
    public static final Integer TOKEN_ERROR = 10030;
    public static final Integer SIGN_ERROR = 10040;
    public static final Integer RUNTIME_ERROR = 10050;
    public static final String Token = "token无效";
    public static final String SIGN = "签名无效";
    @ApiModelProperty(name = "code", value = "业务状态码 10000:成功,10010:参数错误,10020:系统提示, 10030:身份校验异常,10040:签名不通过,10050:系统运行异常")
    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.SYSTEM_INFO, mag, new Object());
    }
    /**
     * 错误信息
     * @return
     */
    public static <T> ResultUtil <T> error(String mag, T obj){
        return ResultUtil.getResult(ResultUtil.SYSTEM_INFO, 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(String...ages){
        return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "【" + ages + "】参数异常", new Object());
    }
    /**
     * 参数异常
     * @return
     */
    public static ResultUtil paranErr(){
        return ResultUtil.getResult(ResultUtil.PARAM_ERROR, "参数异常", new Object());
    }
    /**
     * 运行异常
     * @return
     */
    public static ResultUtil runErr(){
        return ResultUtil.getResult(ResultUtil.RUNTIME_ERROR, "系统运行异常", new Object());
    }
    /**
     * 运行异常
     * @return
     */
    public static <T>ResultUtil<T> runErr(T data){
        return ResultUtil.getResult(ResultUtil.RUNTIME_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, "成功", new Object());
    }
    /**
     * 返回成功
     * @param data
     * @param <T>
     * @return
     */
    public static <T> ResultUtil<T> success(T data){
        return ResultUtil.getResult(ResultUtil.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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/SystemException.java
New file
@@ -0,0 +1,18 @@
package com.supersavedriving.user.modular.system.util;
public class SystemException extends Exception {
    private String msg;
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public SystemException(String msg){
        super(msg);
        this.setMsg(msg);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/UUIDUtil.java
New file
@@ -0,0 +1,78 @@
package com.supersavedriving.user.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 static String getNativeUUID(){
        return UUID.randomUUID().toString();
    }
    /**
     * 生成32位随机码
     * @return
     */
    public static String getRandomCode(){
        return UUIDUtil.getNativeUUID().replaceAll("-", "");
    }
    /**
     * 获取给定长度的随机码
     * @param num
     * @return
     * @throws Exception
     */
    public 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("yyyyMMddhhmmssS");
        return simpleDateFormat.format(new Date());
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/httpClinet/HttpClientUtil.java
New file
@@ -0,0 +1,269 @@
package com.supersavedriving.user.modular.system.util.httpClinet;
import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.databind.ObjectMapper;
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.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.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
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工具类
 */
public class HttpClientUtil {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtil.class);
    private static PoolingHttpClientConnectionManager connectionManager;
    {
        //1.创建连接池管理器
        connectionManager = new PoolingHttpClientConnectionManager(60000,
                TimeUnit.MILLISECONDS);
        connectionManager.setMaxTotal(1000);
        connectionManager.setDefaultMaxPerRoute(50);
    }
    /**
     * 创建一个httpClient对象
     */
    private static CloseableHttpClient getHttpCline(){
        return  HttpClients.custom()
                .setConnectionManager(connectionManager)
                .disableAutomaticRetries()
                .build();
    }
    private static 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 static CloseableHttpResponse setPostHttpRequset(String url, Map<String, Object> params, Map<String, String> header, String contentType) throws Exception{
        HttpPost httpPost = new HttpPost(url);
        httpPost.setConfig(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 static 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 static 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 = 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);
        close(httpResponse);
        return httpResult;
    }
    /**
     * 发送XML请求
     * @param url       请求地址
     * @param xml       XML数据
     * @param header    自定义请求头
     * @return
     */
    public static 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);
        close(httpResponse);
        return httpResult;
    }
    /**
     * 请求https发送XML请求
     * @param url           接口路径
     * @param xml           内容
     * @param header        请求头
     * @param certPassword      证书密码
     * @param certPath      证书路径
     * @param certType      证书类型
     * @return
     * @throws Exception
     */
    public static 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 = 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());
        }
        close(httpResponse);
        httpCline.close();
        return content;
    }
    /**
     * 初始化https对象(带证书)
     * @param key       证书密码
     * @param certPath  证书路径
     * @param certType  证书类型
     * @throws Exception
     */
    private static 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 static 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();
            }
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/httpClinet/HttpResult.java
New file
@@ -0,0 +1,31 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/AES.java
New file
@@ -0,0 +1,72 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/AesException.java
New file
@@ -0,0 +1,59 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/ByteGroup.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.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();
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/PKCS7Encoder.java
New file
@@ -0,0 +1,67 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/SHA1.java
New file
@@ -0,0 +1,61 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.supersavedriving.user.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);
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/SubscribeMessageUtil.java
New file
@@ -0,0 +1,264 @@
package com.supersavedriving.user.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();
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXBizMsgCrypt.java
New file
@@ -0,0 +1,288 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @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.supersavedriving.user.modular.system.util.weChat;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
/**
 * 提供接收和推送给公众平台消息的加解密接口(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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXBizMsgCryptTest.java
New file
@@ -0,0 +1,147 @@
package com.supersavedriving.user.modular.system.util.weChat;
import org.junit.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.StringReader;
import static org.junit.Assert.*;
public class WXBizMsgCryptTest {
    String encodingAesKey = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG";
    String token = "pamtest";
    String timestamp = "1409304348";
    String nonce = "xxxxxx";
    String appId = "wxb11529c136998cb6";
    String replyMsg = "我是中文abcd123";
    String xmlFormat = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";
    String afterAesEncrypt = "jn1L23DB+6ELqJ+6bruv21Y6MD7KeIfP82D6gU39rmkgczbWwt5+3bnyg5K55bgVtVzd832WzZGMhkP72vVOfg==";
    String randomStr = "aaaabbbbccccdddd";
    String replyMsg2 = "<xml><ToUserName><![CDATA[oia2Tj我是中文jewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
    String afterAesEncrypt2 = "jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb";
    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
    }
    @AfterClass
    public static void tearDownAfterClass() throws Exception {
    }
    @Before
    public void setUp() throws Exception {
    }
    @After
    public void tearDown() throws Exception {
    }
    @Test
    public void testNormal() throws ParserConfigurationException, SAXException, IOException {
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
            String afterEncrpt = pc.encryptMsg(replyMsg, timestamp, nonce);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(afterEncrpt);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Encrypt");
            NodeList nodelist2 = root.getElementsByTagName("MsgSignature");
            String encrypt = nodelist1.item(0).getTextContent();
            String msgSignature = nodelist2.item(0).getTextContent();
            String fromXML = String.format(xmlFormat, encrypt);
            // 第三方收到公众号平台发送的消息
            String afterDecrpt = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);
            assertEquals(replyMsg, afterDecrpt);
        } catch (AesException e) {
            fail("正常流程,怎么就抛出异常了??????");
        }
    }
    @Test
    public void testAesEncrypt() {
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
            assertEquals(afterAesEncrypt, pc.encrypt(randomStr, replyMsg));
        } catch (AesException e) {
            e.printStackTrace();
            fail("no异常");
        }
    }
    @Test
    public void testAesEncrypt2() {
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
            assertEquals(afterAesEncrypt2, pc.encrypt(randomStr, replyMsg2));
        } catch (AesException e) {
            e.printStackTrace();
            fail("no异常");
        }
    }
    @Test
    public void testIllegalAesKey() {
        try {
            new WXBizMsgCrypt(token, "abcde", appId);
        } catch (AesException e) {
            assertEquals(AesException.IllegalAesKey, e.getCode());
            return;
        }
        fail("错误流程不抛出异常???");
    }
    @Test
    public void testValidateSignatureError() throws ParserConfigurationException, SAXException,
            IOException {
        try {
            WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
            String afterEncrpt = pc.encryptMsg(replyMsg, timestamp, nonce);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(afterEncrpt);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            NodeList nodelist1 = root.getElementsByTagName("Encrypt");
            String encrypt = nodelist1.item(0).getTextContent();
            String fromXML = String.format(xmlFormat, encrypt);
            pc.decryptMsg("12345", timestamp, nonce, fromXML); // 这里签名错误
        } catch (AesException e) {
            assertEquals(AesException.ValidateSignatureError, e.getCode());
            return;
        }
        fail("错误流程不抛出异常???");
    }
    @Test
    public void testVerifyUrl() throws AesException {
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt("QDG6eK",
                "jWmYm7qr5nMoAUwZRjGtBxmz3KA1tkAj3ykkR6q2B2C", "wx5823bf96d3bd56c7");
        String verifyMsgSig = "5c45ff5e21c57e6ad56bac8758b79b1d9ac89fd3";
        String timeStamp = "1409659589";
        String nonce = "263014780";
        String echoStr = "P9nAzCzyDtyTWESHep1vC5X9xho/qYX3Zpb4yKa9SKld1DsH3Iyt3tP3zNdtp+4RPcs8TgAE7OaBO+FZXvnaqQ==";
        wxcpt.verifyUrl(verifyMsgSig, timeStamp, nonce, echoStr);
        // 只要不抛出异常就好
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WXCore.java
New file
@@ -0,0 +1,52 @@
package com.supersavedriving.user.modular.system.util.weChat;
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));
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WeChatUtil.java
New file
@@ -0,0 +1,415 @@
package com.supersavedriving.user.modular.system.util.weChat;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.supersavedriving.user.core.util.ToolUtil;
import com.supersavedriving.user.modular.system.util.RedisUtil;
import com.supersavedriving.user.modular.system.util.UUIDUtil;
import com.supersavedriving.user.modular.system.util.httpClinet.HttpClientUtil;
import com.supersavedriving.user.modular.system.util.httpClinet.HttpResult;
import com.supersavedriving.user.modular.system.util.weChat.model.Code2Session;
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.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
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 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失败");
                                    return;
                                }
                                redisUtil.setStrValue("wxAppletsAccessToken", wxAppletsAccessToken, 7000);
                            }catch (Exception e){
                                e.printStackTrace();
                            }
                        }
                    }, 0, 7000000);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }).start();
    }
    /**
     * 小程序使用jscode获取openid
     * @param jscode
     * @return
     */
    public Code2Session 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;
        }
        Code2Session code2Session = JSON.parseObject(httpResult.getData(), Code2Session.class);
        return code2Session;
    }
    /**
     * 获取微信小程序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<String> exchange = restTemplate.exchange(url, HttpMethod.POST, requestEntity, String.class, new Object[0]);
            String body1 = exchange.getBody();
//            System.err.println(body1);
            ResponseEntity<byte[]> entity  = restTemplate.exchange(url, HttpMethod.POST, requestEntity, byte[].class, new Object[0]);
            byte[] body = entity.getBody();
//            System.err.println(Base64.encodeBase64String(body));
            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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/WxPKCS7Encoder.java
New file
@@ -0,0 +1,63 @@
package com.supersavedriving.user.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;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/XMLParse.java
New file
@@ -0,0 +1,71 @@
/**
 * 对公众平台发送给公众账号的消息加解密示例代码.
 *
 * @copyright Copyright (c) 1998-2014 Tencent Inc.
 */
// ------------------------------------------------------------------------
package com.supersavedriving.user.modular.system.util.weChat;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.StringReader;
/**
 * 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);
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/Category.java
New file
@@ -0,0 +1,18 @@
package com.supersavedriving.user.modular.system.util.weChat.model;
import lombok.Data;
/**
 * 订阅消息类目
 */
@Data
public class Category {
    /**
     * 类目id
     */
    private String id;
    /**
     * 类目名称
     */
    private String name;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/Code2Session.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.modular.system.util.weChat.model;
import lombok.Data;
/**
 * TODO
 *
 * @author 39373
 * @date 2023/2/26 19:42
 */
@Data
public class Code2Session {
    /**
     * 状态码(-1=系统繁忙,0=成功,40029=code无效,45011=频率限制,每个用户每分钟100次,40226=高风险等级用户,小程序登录拦截 )
     */
    private Integer errcode;
    /**
     * 状态说明
     */
    private String errmsg;
    /**
     * openid
     */
    private String openid;
    /**
     * sessionKey
     */
    private String session_key;
    /**
     * unionid
     */
    private String unionid;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/KeywordEnum.java
New file
@@ -0,0 +1,17 @@
package com.supersavedriving.user.modular.system.util.weChat.model;
import lombok.Data;
import java.util.List;
@Data
public class KeywordEnum {
    /**
     * 枚举参数的 key
     */
    private String keywordCode;
    /**
     * 枚举参数值范围列表
     */
    private List<String> enumValueList;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/MessageTemplate.java
New file
@@ -0,0 +1,36 @@
package com.supersavedriving.user.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;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/PubTemplateKeywords.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.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;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/util/weChat/model/PubTemplatetitles.java
New file
@@ -0,0 +1,26 @@
package com.supersavedriving.user.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;
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/ActivityWarpper.java
New file
@@ -0,0 +1,38 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("活动")
public class ActivityWarpper {
    @ApiModelProperty("活动id")
    private Integer id;
    @ApiModelProperty("活动描述")
    private String content;
    @ApiModelProperty("完成情况")
    private String carryOut;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getCarryOut() {
        return carryOut;
    }
    public void setCarryOut(String carryOut) {
        this.carryOut = carryOut;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/BaseWarpper.java
New file
@@ -0,0 +1,171 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
 * 公共封装类
 */
@ApiModel("公共对象")
public class BaseWarpper {
    @ApiModelProperty("主键id")
    private Integer id;
    @ApiModelProperty("名称")
    private String name;
    @ApiModelProperty("内容")
    private String content;
    @ApiModelProperty("数量")
    private Integer number;
    @ApiModelProperty("金额")
    private Double amount;
    @ApiModelProperty("时长(分钟)")
    private Integer minute;
    @ApiModelProperty("经度")
    private Double lon;
    @ApiModelProperty("纬度")
    private Double lat;
    @ApiModelProperty("日期")
    private String day;
    @ApiModelProperty("其他内容")
    private Object data;
    public BaseWarpper() {
        this.id = 0;
        this.name = "";
        this.content = "";
        this.number = 0;
        this.amount = 0D;
        this.minute = 0;
        this.lon = 0D;
        this.lat = 0D;
        this.day = "";
    }
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public Integer getNumber() {
        return number;
    }
    public void setNumber(Integer number) {
        this.number = number;
    }
    public Double getAmount() {
        return amount;
    }
    public void setAmount(Double amount) {
        this.amount = amount;
    }
    public Integer getMinute() {
        return minute;
    }
    public void setMinute(Integer minute) {
        this.minute = minute;
    }
    public Double getLon() {
        return lon;
    }
    public void setLon(Double lon) {
        this.lon = lon;
    }
    public Double getLat() {
        return lat;
    }
    public void setLat(Double lat) {
        this.lat = lat;
    }
    public String getDay() {
        return day;
    }
    public void setDay(String day) {
        this.day = day;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    @Override
    public String toString() {
        return "BaseWarpper{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", content='" + content + '\'' +
                ", number=" + number +
                ", amount=" + amount +
                ", minute=" + minute +
                ", lon=" + lon +
                ", lat=" + lat +
                ", day='" + day + '\'' +
                ", data=" + data +
                '}';
    }
    public static BaseWarpper getBaseWarpper(Map<String, Object> map){
        BaseWarpper baseWarpper = new BaseWarpper();
        if(null != map){
            baseWarpper.setId(null != map.get("id") ? Integer.valueOf(map.get("id").toString()) : 0);
            baseWarpper.setName(null != map.get("name") ? map.get("name").toString() : "");
            baseWarpper.setContent(null != map.get("content") ? map.get("content").toString() : "");
            baseWarpper.setNumber(null != map.get("number") ? Integer.valueOf(map.get("number").toString()) : 0);
            baseWarpper.setAmount(null != map.get("amount") ? Double.valueOf(map.get("amount").toString()) : 0);
            baseWarpper.setMinute(null != map.get("minute") ? Integer.valueOf(map.get("minute").toString()) : 0);
            baseWarpper.setLon(null != map.get("lon") ? Double.valueOf(map.get("lon").toString()) : 0.0);
            baseWarpper.setLat(null != map.get("lat") ? Double.valueOf(map.get("lat").toString()) : 0.0);
            baseWarpper.setDay(null != map.get("day") ? map.get("day").toString() : "");
            baseWarpper.setData(null != map.get("data") ? map.get("data") : new Object());
        }
        return baseWarpper;
    }
    public static List<BaseWarpper> getBaseWarppers(List<Map<String, Object>> list){
        List<BaseWarpper> data = new ArrayList<>();
        if(null != list){
            for(Map<String, Object> map : list){
                data.add(BaseWarpper.getBaseWarpper(map));
            }
        }
        return data;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DeptWarpper.java
New file
@@ -0,0 +1,33 @@
package com.supersavedriving.user.modular.system.warpper;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.base.warpper.BaseControllerWarpper;
import com.supersavedriving.user.core.util.ToolUtil;
import java.util.Map;
/**
 * 部门列表的包装
 *
 * @author fengshuonan
 * @date 2017年4月25日 18:10:31
 */
public class DeptWarpper extends BaseControllerWarpper {
    public DeptWarpper(Object list) {
        super(list);
    }
    @Override
    public void warpTheMap(Map<String, Object> map) {
        Integer pid = (Integer) map.get("pid");
        if (ToolUtil.isEmpty(pid) || pid.equals(0)) {
            map.put("pName", "--");
        } else {
            map.put("pName", ConstantFactory.me().getDeptName(pid));
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DictWarpper.java
New file
@@ -0,0 +1,36 @@
package com.supersavedriving.user.modular.system.warpper;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.modular.system.model.Dict;
import com.supersavedriving.user.core.base.warpper.BaseControllerWarpper;
import com.supersavedriving.user.core.util.ToolUtil;
import java.util.List;
import java.util.Map;
/**
 * 字典列表的包装
 *
 * @author fengshuonan
 * @date 2017年4月25日 18:10:31
 */
public class DictWarpper extends BaseControllerWarpper {
    public DictWarpper(Object list) {
        super(list);
    }
    @Override
    public void warpTheMap(Map<String, Object> map) {
        StringBuffer detail = new StringBuffer();
        Integer id = Integer.valueOf(map.get("id").toString());
        List<Dict> dicts = ConstantFactory.me().findInDict(id);
        if(dicts != null){
            for (Dict dict : dicts) {
                detail.append(dict.getCode() + ":" +dict.getName() + ",");
            }
            map.put("detail", ToolUtil.removeSuffix(detail.toString(),","));
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/DriverInfoWarpper.java
New file
@@ -0,0 +1,359 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Map;
@ApiModel("个人中心详情")
public class DriverInfoWarpper {
    @ApiModelProperty("司机id(用于生成二维码)")
    private Integer id;
    @ApiModelProperty("头像")
    private String avatar;
    @ApiModelProperty("姓名")
    private String name;
    @ApiModelProperty("电话")
    private String phone;
    @ApiModelProperty("性别")
    private Integer sex;
    @ApiModelProperty("车牌")
    private String licensePlate;
    @ApiModelProperty("车辆品牌")
    private String brand;
    @ApiModelProperty("车辆颜色")
    private String carColor;
    @ApiModelProperty("历史接单数")
    private Integer orderNum;
    @ApiModelProperty("评分")
    private Double score;
    @ApiModelProperty("账户余额")
    private Double balance;
    @ApiModelProperty("活动总收入")
    private Double activityMoney;
    @ApiModelProperty("剩余可提现活动收入")
    private Double laveActivityMoney;
    @ApiModelProperty("历史总收入")
    private Double businessMoney;
    @ApiModelProperty("剩余可提现收入")
    private Double laveBusinessMoney;
    @ApiModelProperty("出租车资格证号")
    private String taxiAptitudeCard;
    @ApiModelProperty("发证日期")
    private String networkCarlssueDate;
    @ApiModelProperty("公司")
    private String company;
    @ApiModelProperty("居住地(带分隔符)")
    private String driverContactAddress_;
    @ApiModelProperty("身份证号码")
    private String idCard;
    @ApiModelProperty("身份证正面照")
    private String idCardImgUrl1;
    @ApiModelProperty("身份证背面照")
    private String idCardImgUrl2;
    @ApiModelProperty("初次领取驾驶证日期")
    private String getDriverLicenseDate;
    @ApiModelProperty("服务模式(1=专车,2=出租车,3=城际,4=小件物流-同城,5=小件物流-跨城,6=包车)多个以逗号分隔")
    private String type;
    @ApiModelProperty("从业地(带分隔符)")
    private String placeOfPractice;
    @ApiModelProperty("从业地行政区域代码")
    private String placeOfEmployment;
    @ApiModelProperty("驾驶证照片")
    private String driveCardImgUrl;
    @ApiModelProperty("网约车资格证照片")
    private String networkCarlssueImg;
    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 getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getSex() {
        return sex;
    }
    public void setSex(Integer sex) {
        this.sex = sex;
    }
    public String getLicensePlate() {
        return licensePlate;
    }
    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public String getCarColor() {
        return carColor;
    }
    public void setCarColor(String carColor) {
        this.carColor = carColor;
    }
    public Integer getOrderNum() {
        return orderNum;
    }
    public void setOrderNum(Integer orderNum) {
        this.orderNum = orderNum;
    }
    public Double getScore() {
        return score;
    }
    public void setScore(Double score) {
        this.score = score;
    }
    public Double getBalance() {
        return balance;
    }
    public void setBalance(Double balance) {
        this.balance = balance;
    }
    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public Double getActivityMoney() {
        return activityMoney;
    }
    public void setActivityMoney(Double activityMoney) {
        this.activityMoney = activityMoney;
    }
    public Double getBusinessMoney() {
        return businessMoney;
    }
    public void setBusinessMoney(Double businessMoney) {
        this.businessMoney = businessMoney;
    }
    public String getTaxiAptitudeCard() {
        return taxiAptitudeCard;
    }
    public void setTaxiAptitudeCard(String taxiAptitudeCard) {
        this.taxiAptitudeCard = taxiAptitudeCard;
    }
    public String getNetworkCarlssueDate() {
        return networkCarlssueDate;
    }
    public void setNetworkCarlssueDate(String networkCarlssueDate) {
        this.networkCarlssueDate = networkCarlssueDate;
    }
    public String getCompany() {
        return company;
    }
    public void setCompany(String company) {
        this.company = company;
    }
    public String getDriverContactAddress_() {
        return driverContactAddress_;
    }
    public void setDriverContactAddress_(String driverContactAddress_) {
        this.driverContactAddress_ = driverContactAddress_;
    }
    public String getIdCard() {
        return idCard;
    }
    public void setIdCard(String idCard) {
        this.idCard = idCard;
    }
    public String getIdCardImgUrl1() {
        return idCardImgUrl1;
    }
    public void setIdCardImgUrl1(String idCardImgUrl1) {
        this.idCardImgUrl1 = idCardImgUrl1;
    }
    public String getIdCardImgUrl2() {
        return idCardImgUrl2;
    }
    public void setIdCardImgUrl2(String idCardImgUrl2) {
        this.idCardImgUrl2 = idCardImgUrl2;
    }
    public String getGetDriverLicenseDate() {
        return getDriverLicenseDate;
    }
    public void setGetDriverLicenseDate(String getDriverLicenseDate) {
        this.getDriverLicenseDate = getDriverLicenseDate;
    }
    public String getType() {
        return type;
    }
    public void setType(String type) {
        this.type = type;
    }
    public String getPlaceOfPractice() {
        return placeOfPractice;
    }
    public void setPlaceOfPractice(String placeOfPractice) {
        this.placeOfPractice = placeOfPractice;
    }
    public String getDriveCardImgUrl() {
        return driveCardImgUrl;
    }
    public void setDriveCardImgUrl(String driveCardImgUrl) {
        this.driveCardImgUrl = driveCardImgUrl;
    }
    public String getNetworkCarlssueImg() {
        return networkCarlssueImg;
    }
    public void setNetworkCarlssueImg(String networkCarlssueImg) {
        this.networkCarlssueImg = networkCarlssueImg;
    }
    public String getPlaceOfEmployment() {
        return placeOfEmployment;
    }
    public void setPlaceOfEmployment(String placeOfEmployment) {
        this.placeOfEmployment = placeOfEmployment;
    }
    public Double getLaveActivityMoney() {
        return laveActivityMoney;
    }
    public void setLaveActivityMoney(Double laveActivityMoney) {
        this.laveActivityMoney = laveActivityMoney;
    }
    public Double getLaveBusinessMoney() {
        return laveBusinessMoney;
    }
    public void setLaveBusinessMoney(Double laveBusinessMoney) {
        this.laveBusinessMoney = laveBusinessMoney;
    }
    @Override
    public String toString() {
        return "DriverInfoWarpper{" +
                "id=" + id +
                ", avatar='" + avatar + '\'' +
                ", name='" + name + '\'' +
                ", phone='" + phone + '\'' +
                ", sex=" + sex +
                ", licensePlate='" + licensePlate + '\'' +
                ", brand='" + brand + '\'' +
                ", carColor='" + carColor + '\'' +
                ", orderNum=" + orderNum +
                ", score=" + score +
                ", balance=" + balance +
                ", activityMoney=" + activityMoney +
                ", laveActivityMoney=" + laveActivityMoney +
                ", businessMoney=" + businessMoney +
                ", laveBusinessMoney=" + laveBusinessMoney +
                ", taxiAptitudeCard='" + taxiAptitudeCard + '\'' +
                ", networkCarlssueDate='" + networkCarlssueDate + '\'' +
                ", company='" + company + '\'' +
                ", driverContactAddress_='" + driverContactAddress_ + '\'' +
                ", idCard='" + idCard + '\'' +
                ", idCardImgUrl1='" + idCardImgUrl1 + '\'' +
                ", idCardImgUrl2='" + idCardImgUrl2 + '\'' +
                ", getDriverLicenseDate='" + getDriverLicenseDate + '\'' +
                ", type='" + type + '\'' +
                ", placeOfPractice='" + placeOfPractice + '\'' +
                ", placeOfEmployment='" + placeOfEmployment + '\'' +
                ", driveCardImgUrl='" + driveCardImgUrl + '\'' +
                ", networkCarlssueImg='" + networkCarlssueImg + '\'' +
                '}';
    }
    public static DriverInfoWarpper getDriverInfoWarpper(Map<String, Object> map){
        DriverInfoWarpper driverInfoWarpper = new DriverInfoWarpper();
        if(null != map){
            driverInfoWarpper.setId(null != map.get("id") ? Integer.valueOf(String.valueOf(map.get("id"))) : 0);
            driverInfoWarpper.setAvatar(null != map.get("avatar") ? String.valueOf(map.get("avatar")) : "");
            driverInfoWarpper.setName(null != map.get("name") ? String.valueOf(map.get("name")) : "");
            driverInfoWarpper.setPhone(null != map.get("phone") ? String.valueOf(map.get("phone")) : "");
            driverInfoWarpper.setSex(null != map.get("sex") ? Integer.valueOf(String.valueOf(map.get("sex"))) : 0);
            driverInfoWarpper.setLicensePlate(null != map.get("licensePlate") ? String.valueOf(map.get("licensePlate")) : "");
            driverInfoWarpper.setBrand(null != map.get("brand") ? String.valueOf(map.get("brand")) : "");
            driverInfoWarpper.setCarColor(null != map.get("carColor") ? String.valueOf(map.get("carColor")) : "");
            driverInfoWarpper.setOrderNum(null != map.get("orderNum") ? Integer.valueOf(String.valueOf(map.get("orderNum"))) : 0);
            driverInfoWarpper.setScore(null != map.get("score") ? Double.valueOf(String.valueOf(map.get("score"))) : 0);
            driverInfoWarpper.setBalance(null != map.get("balance") ? Double.valueOf(String.valueOf(map.get("balance"))) : 0);
            driverInfoWarpper.setActivityMoney(null != map.get("activityMoney") ? Double.valueOf(String.valueOf(map.get("activityMoney"))) : 0);
            driverInfoWarpper.setBusinessMoney(null != map.get("businessMoney") ? Double.valueOf(String.valueOf(map.get("businessMoney"))) : 0);
            driverInfoWarpper.setTaxiAptitudeCard(null != map.get("taxiAptitudeCard") ? String.valueOf(map.get("taxiAptitudeCard")) : "");
            driverInfoWarpper.setNetworkCarlssueDate(null != map.get("networkCarlssueDate") ? String.valueOf(map.get("networkCarlssueDate")) : "");
            driverInfoWarpper.setCompany(null != map.get("company") ? String.valueOf(map.get("company")) : "");
            driverInfoWarpper.setDriverContactAddress_(null != map.get("driverContactAddress_") ? String.valueOf(map.get("driverContactAddress_")) : "");
            driverInfoWarpper.setIdCard(null != map.get("idCard") ? String.valueOf(map.get("idCard")) : "");
            driverInfoWarpper.setIdCardImgUrl1(null != map.get("idCardImgUrl1") ? String.valueOf(map.get("idCardImgUrl1")) : "");
            driverInfoWarpper.setIdCardImgUrl2(null != map.get("idCardImgUrl2") ? String.valueOf(map.get("idCardImgUrl2")) : "");
            driverInfoWarpper.setGetDriverLicenseDate(null != map.get("getDriverLicenseDate") ? String.valueOf(map.get("getDriverLicenseDate")) : "");
            driverInfoWarpper.setType(null != map.get("type") ? String.valueOf(map.get("type")) : "");
            driverInfoWarpper.setPlaceOfPractice(null != map.get("placeOfPractice") ? String.valueOf(map.get("placeOfPractice")) : "");
            driverInfoWarpper.setDriveCardImgUrl(null != map.get("driveCardImgUrl") ? String.valueOf(map.get("driveCardImgUrl")) : "");
            driverInfoWarpper.setNetworkCarlssueImg(null != map.get("networkCarlssueImg") ? String.valueOf(map.get("networkCarlssueImg")) : "");
            driverInfoWarpper.setPlaceOfEmployment(null != map.get("placeOfEmployment") ? String.valueOf(map.get("placeOfEmployment")) : "");
            driverInfoWarpper.setLaveActivityMoney(null != map.get("laveActivityMoney") ? Double.valueOf(String.valueOf(map.get("laveActivityMoney"))) : 0);
            driverInfoWarpper.setLaveBusinessMoney(null != map.get("laveBusinessMoney") ? Double.valueOf(String.valueOf(map.get("laveBusinessMoney"))) : 0);
        }
        return driverInfoWarpper;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/HomeWarpper.java
New file
@@ -0,0 +1,115 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Map;
@ApiModel("首页统计")
public class HomeWarpper {
    @ApiModelProperty("车牌号")
    private String licensePlate;
    @ApiModelProperty("车辆品牌")
    private String brand;
    @ApiModelProperty("今日接单")
    private Integer dayNum;
    @ApiModelProperty("月接单")
    private Integer mouthNum;
    @ApiModelProperty("评分")
    private Double score;
    @ApiModelProperty("活动数")
    private Integer activity;
    @ApiModelProperty("上下班状态(1=上班,2=下班)")
    private Integer work;
    public String getLicensePlate() {
        return licensePlate;
    }
    public void setLicensePlate(String licensePlate) {
        this.licensePlate = licensePlate;
    }
    public String getBand() {
        return brand;
    }
    public void setBand(String brand) {
        this.brand = brand;
    }
    public Integer getDayNum() {
        return dayNum;
    }
    public void setDayNum(Integer dayNum) {
        this.dayNum = dayNum;
    }
    public Integer getMouthNum() {
        return mouthNum;
    }
    public void setMouthNum(Integer mouthNum) {
        this.mouthNum = mouthNum;
    }
    public Double getScore() {
        return score;
    }
    public void setScore(Double score) {
        this.score = score;
    }
    public Integer getActivity() {
        return activity;
    }
    public void setActivity(Integer activity) {
        this.activity = activity;
    }
    public String getBrand() {
        return brand;
    }
    public void setBrand(String brand) {
        this.brand = brand;
    }
    public Integer getWork() {
        return work;
    }
    public void setWork(Integer work) {
        this.work = work;
    }
    @Override
    public String toString() {
        return "HomeWarpper{" +
                "licensePlate='" + licensePlate + '\'' +
                ", brand='" + brand + '\'' +
                ", dayNum=" + dayNum +
                ", mouthNum=" + mouthNum +
                ", score=" + score +
                ", activity=" + activity +
                ", work=" + work +
                '}';
    }
    public static HomeWarpper getHomeWarpper(Map<String, Object> map){
        HomeWarpper homeWarpper = new HomeWarpper();
        if(null != map){
            homeWarpper.setLicensePlate(null != map.get("licensePlate") ? String.valueOf(map.get("licensePlate")) : "");
            homeWarpper.setBand(null != map.get("brand") ? String.valueOf(map.get("brand")) : "");
            homeWarpper.setDayNum(null != map.get("dayNum") ? Integer.valueOf(String.valueOf(map.get("dayNum"))) : 0);
            homeWarpper.setMouthNum(null != map.get("mouthNum") ? Integer.valueOf(String.valueOf(map.get("mouthNum"))) : 0);
            homeWarpper.setScore(null != map.get("score") ? Double.valueOf(String.valueOf(map.get("score"))) : 0);
            homeWarpper.setActivity(null != map.get("activity") ? Integer.valueOf(String.valueOf(map.get("activity"))) : 0);
            homeWarpper.setWork(null != map.get("work") ? Integer.valueOf(String.valueOf(map.get("work"))) : 0);
        }
        return homeWarpper;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/LogWarpper.java
New file
@@ -0,0 +1,44 @@
package com.supersavedriving.user.modular.system.warpper;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.base.warpper.BaseControllerWarpper;
import com.supersavedriving.user.core.util.Contrast;
import com.supersavedriving.user.core.util.ToolUtil;
import java.util.Map;
/**
 * 日志列表的包装类
 *
 * @author fengshuonan
 * @date 2017年4月5日22:56:24
 */
public class LogWarpper extends BaseControllerWarpper {
    public LogWarpper(Object list) {
        super(list);
    }
    @Override
    public void warpTheMap(Map<String, Object> map) {
        String message = (String) map.get("message");
        Integer userid = (Integer) map.get("userid");
        map.put("userName", ConstantFactory.me().getUserNameById(userid));
        //如果信息过长,则只截取前100位字符串
        if (ToolUtil.isNotEmpty(message) && message.length() >= 100) {
            String subMessage = message.substring(0, 100) + "...";
            map.put("message", subMessage);
        }
        //如果信息中包含分割符号;;;   则分割字符串返给前台
        if (ToolUtil.isNotEmpty(message) && message.indexOf(Contrast.separator) != -1) {
            String[] msgs = message.split(Contrast.separator);
            map.put("regularMessage",msgs);
        }else{
            map.put("regularMessage",message);
        }
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/LoginWarpper.java
New file
@@ -0,0 +1,58 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel("登录")
public class LoginWarpper {
    @ApiModelProperty("用户id")
    private Integer id;
    @ApiModelProperty("token")
    private String token;
    @ApiModelProperty("appid")
    private String appid;
    @ApiModelProperty("高德猎鹰服务id")
    private String serverId;
    @ApiModelProperty("高德猎鹰终端id")
    private String terminalId;
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
    public String getAppid() {
        return appid;
    }
    public void setAppid(String appid) {
        this.appid = appid;
    }
    public String getServerId() {
        return serverId;
    }
    public void setServerId(String serverId) {
        this.serverId = serverId;
    }
    public String getTerminalId() {
        return terminalId;
    }
    public void setTerminalId(String terminalId) {
        this.terminalId = terminalId;
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/MenuWarpper.java
New file
@@ -0,0 +1,28 @@
package com.supersavedriving.user.modular.system.warpper;
import com.supersavedriving.user.core.base.warpper.BaseControllerWarpper;
import com.supersavedriving.user.core.common.constant.factory.ConstantFactory;
import com.supersavedriving.user.core.constant.IsMenu;
import java.util.List;
import java.util.Map;
/**
 * 菜单列表的包装类
 *
 * @author fengshuonan
 * @date 2017年2月19日15:07:29
 */
public class MenuWarpper extends BaseControllerWarpper {
    public MenuWarpper(List<Map<String, Object>> list) {
        super(list);
    }
    @Override
    public void warpTheMap(Map<String, Object> map) {
        map.put("statusName", ConstantFactory.me().getMenuStatusName((Integer) map.get("status")));
        map.put("isMenuName", IsMenu.valueOf((Integer) map.get("ismenu")));
    }
}
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/MoneyInfoWarpper.java
New file
@@ -0,0 +1,229 @@
package com.supersavedriving.user.modular.system.warpper;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import java.util.Map;
/**
 * 费用明细
 */
@ApiModel("费用明细")
public class MoneyInfoWarpper {
    @ApiModelProperty("订单总金额")
    private Double orderMoney;
    @ApiModelProperty("起步里程")
    private Double startMileage;
    @ApiModelProperty("起步价")
    private Double startMoney;
    @ApiModelProperty("里程费")
    private Double mileageMoney;
    @ApiModelProperty("里程数")
    private Double mileage;
    @ApiModelProperty("时长费")
    private Double durationMoney;
    @ApiModelProperty("时长")
    private Double duration;
    @ApiModelProperty("等待费")
    private Double waitMoney;
    @ApiModelProperty("等待时长")
    private Double wait;
    @ApiModelProperty("远途费")
    private Double longDistanceMoney;
    @ApiModelProperty("远途里程")
    private Double longDistance;
    @ApiModelProperty("停车费")
    private Double parkMoney;
    @ApiModelProperty("过路费")
    private Double roadTollMoney;
    @ApiModelProperty("红包抵扣金额")
    private Double redPacketMoney;
    @ApiModelProperty("优惠券抵扣金额")
    private Double couponMoney;
    @ApiModelProperty("折扣抵扣金额")
    private Double discountMoney;
    @ApiModelProperty("折扣")
    private Double discount;
    public Double getOrderMoney() {
        return orderMoney;
    }
    public void setOrderMoney(Double orderMoney) {
        this.orderMoney = orderMoney;
    }
    public Double getStartMoney() {
        return startMoney;
    }
    public void setStartMoney(Double startMoney) {
        this.startMoney = startMoney;
    }
    public Double getMileageMoney() {
        return mileageMoney;
    }
    public void setMileageMoney(Double mileageMoney) {
        this.mileageMoney = mileageMoney;
    }
    public Double getDurationMoney() {
        return durationMoney;
    }
    public void setDurationMoney(Double durationMoney) {
        this.durationMoney = durationMoney;
    }
    public Double getWaitMoney() {
        return waitMoney;
    }
    public void setWaitMoney(Double waitMoney) {
        this.waitMoney = waitMoney;
    }
    public Double getLongDistanceMoney() {
        return longDistanceMoney;
    }
    public void setLongDistanceMoney(Double longDistanceMoney) {
        this.longDistanceMoney = longDistanceMoney;
    }
    public Double getParkMoney() {
        return parkMoney;
    }
    public void setParkMoney(Double parkMoney) {
        this.parkMoney = parkMoney;
    }
    public Double getRoadTollMoney() {
        return roadTollMoney;
    }
    public void setRoadTollMoney(Double roadTollMoney) {
        this.roadTollMoney = roadTollMoney;
    }
    public Double getRedPacketMoney() {
        return redPacketMoney;
    }
    public void setRedPacketMoney(Double redPacketMoney) {
        this.redPacketMoney = redPacketMoney;
    }
    public Double getCouponMoney() {
        return couponMoney;
    }
    public void setCouponMoney(Double couponMoney) {
        this.couponMoney = couponMoney;
    }
    public Double getDiscountMoney() {
        return discountMoney;
    }
    public void setDiscountMoney(Double discountMoney) {
        this.discountMoney = discountMoney;
    }
    public Double getDiscount() {
        return discount;
    }
    public void setDiscount(Double discount) {
        this.discount = discount;
    }
    public Double getMileage() {
        return mileage;
    }
    public void setMileage(Double mileage) {
        this.mileage = mileage;
    }
    public Double getDuration() {
        return duration;
    }
    public void setDuration(Double duration) {
        this.duration = duration;
    }
    public Double getWait() {
        return wait;
    }
    public void setWait(Double wait) {
        this.wait = wait;
    }
    public Double getLongDistance() {
        return longDistance;
    }
    public void setLongDistance(Double longDistance) {
        this.longDistance = longDistance;
    }
    public Double getStartMileage() {
        return startMileage;
    }
    public void setStartMileage(Double startMileage) {
        this.startMileage = startMileage;
    }
    @Override
    public String toString() {
        return "MoneyInfoWarpper{" +
                "orderMoney=" + orderMoney +
                ", startMoney=" + startMoney +
                ", mileageMoney=" + mileageMoney +
                ", mileage=" + mileage +
                ", durationMoney=" + durationMoney +
                ", duration=" + duration +
                ", waitMoney=" + waitMoney +
                ", wait=" + wait +
                ", longDistanceMoney=" + longDistanceMoney +
                ", longDistance=" + longDistance +
                ", parkMoney=" + parkMoney +
                ", roadTollMoney=" + roadTollMoney +
                ", redPacketMoney=" + redPacketMoney +
                ", couponMoney=" + couponMoney +
                ", discountMoney=" + discountMoney +
                ", discount=" + discount +
                '}';
    }
    public static MoneyInfoWarpper getMoneyInfoWarpper(Map<String, Object> map){
        MoneyInfoWarpper moneyInfoWarpper = new MoneyInfoWarpper();
        if(null != map){
            moneyInfoWarpper.setOrderMoney(null != map.get("orderMoney") ? Double.valueOf(map.get("orderMoney").toString()) : 0D);
            moneyInfoWarpper.setStartMileage(null != map.get("startMileage") ? Double.valueOf(map.get("startMileage").toString()) : 0D);
            moneyInfoWarpper.setStartMoney(null != map.get("startMoney") ? Double.valueOf(map.get("startMoney").toString()) : 0D);
            moneyInfoWarpper.setMileage(null != map.get("mileageKilometers") ? Double.valueOf(map.get("mileageKilometers").toString()) : 0D);
            moneyInfoWarpper.setMileageMoney(null != map.get("mileageMoney") ? Double.valueOf(map.get("mileageMoney").toString()) : 0D);
            moneyInfoWarpper.setDuration(null != map.get("duration") ? Double.valueOf(map.get("duration").toString()) : 0D);
            moneyInfoWarpper.setDurationMoney(null != map.get("durationMoney") ? Double.valueOf(map.get("durationMoney").toString()) : 0D);
            moneyInfoWarpper.setWait(null != map.get("wait") ? Double.valueOf(map.get("wait").toString()) : 0D);
            moneyInfoWarpper.setWaitMoney(null != map.get("waitMoney") ? Double.valueOf(map.get("waitMoney").toString()) : 0D);
            moneyInfoWarpper.setLongDistance(null != map.get("longDistance") ? Double.valueOf(map.get("longDistance").toString()) : 0D);
            moneyInfoWarpper.setLongDistanceMoney(null != map.get("longDistanceMoney") ? Double.valueOf(map.get("longDistanceMoney").toString()) : 0D);
            moneyInfoWarpper.setParkMoney(null != map.get("parkMoney") ? Double.valueOf(map.get("parkMoney").toString()) : 0D);
            moneyInfoWarpper.setRoadTollMoney(null != map.get("roadTollMoney") ? Double.valueOf(map.get("roadTollMoney").toString()) : 0D);
            moneyInfoWarpper.setRedPacketMoney(null != map.get("redPacketMoney") ? Double.valueOf(map.get("redPacketMoney").toString()) : 0D);
            moneyInfoWarpper.setCouponMoney(null != map.get("couponMoney") ? Double.valueOf(map.get("couponMoney").toString()) : 0D);
            moneyInfoWarpper.setDiscountMoney(null != map.get("discountMoney") ? Double.valueOf(map.get("discountMoney").toString()) : 0D);
            moneyInfoWarpper.setDiscount(null != map.get("discount") ? Double.valueOf(map.get("discount").toString()) : 0D);
        }
        return moneyInfoWarpper;
    }
}
Diff truncated after the above file
user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/NoticeWrapper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderEvaluateWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderInfoWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderListWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrderStatusWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/OrdersWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/RegisteredWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/ResponseWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/RoleWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/SignInToRegister.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/SystemNoticeWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/UserWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/VersionWarpper.java user/guns-admin/src/main/java/com/supersavedriving/user/modular/system/warpper/WithdrawalWarpper.java user/guns-admin/src/main/resources/META-INF/spring-devtools.properties user/guns-admin/src/main/resources/application.yml user/guns-admin/src/main/resources/ehcache.xml user/guns-admin/src/main/resources/logback-spring.xml user/guns-admin/src/main/resources/redis.properties user/guns-admin/src/main/webapp/WEB-INF/view/404.html user/guns-admin/src/main/webapp/WEB-INF/view/blackboard.html user/guns-admin/src/main/webapp/WEB-INF/view/code/code.html user/guns-admin/src/main/webapp/WEB-INF/view/common/_container.html user/guns-admin/src/main/webapp/WEB-INF/view/common/_right.html user/guns-admin/src/main/webapp/WEB-INF/view/common/_tab.html user/guns-admin/src/main/webapp/WEB-INF/view/common/_theme.html user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/NameCon.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/SelectCon.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/TimeCon.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/avatar.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/button.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/input.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/select.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/table.tag user/guns-admin/src/main/webapp/WEB-INF/view/common/tags/tag_tips user/guns-admin/src/main/webapp/WEB-INF/view/index.html user/guns-admin/src/main/webapp/WEB-INF/view/login.html user/guns-admin/src/main/webapp/WEB-INF/view/system/code/code.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dept/dept_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/dict/dict_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/log/log.html user/guns-admin/src/main/webapp/WEB-INF/view/system/log/login_log.html user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu.html user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/menu/menu_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice.html user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/notice/notice_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role.html user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_assign.html user/guns-admin/src/main/webapp/WEB-INF/view/system/role/role_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_add.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_chpwd.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_edit.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_roleassign.html user/guns-admin/src/main/webapp/WEB-INF/view/system/user/user_view.html user/guns-admin/src/main/webapp/static/css/_fstyle.css user/guns-admin/src/main/webapp/static/css/bootstrap-rtl.css user/guns-admin/src/main/webapp/static/css/bootstrap.min.css user/guns-admin/src/main/webapp/static/css/font-awesome.css user/guns-admin/src/main/webapp/static/css/font-awesome.min.css user/guns-admin/src/main/webapp/static/css/login.css user/guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-1.png user/guns-admin/src/main/webapp/static/css/patterns/header-profile-skin-3.png user/guns-admin/src/main/webapp/static/css/patterns/header-profile.png user/guns-admin/src/main/webapp/static/css/patterns/shattered.png user/guns-admin/src/main/webapp/static/css/plugins/bootstrap-table/bootstrap-table.min.css user/guns-admin/src/main/webapp/static/css/plugins/bootstrap-treetable/bootstrap-treetable.css user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite.png user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen-sprite@2x.png user/guns-admin/src/main/webapp/static/css/plugins/chosen/chosen.css user/guns-admin/src/main/webapp/static/css/plugins/iCheck/custom.css user/guns-admin/src/main/webapp/static/css/plugins/iCheck/green.png user/guns-admin/src/main/webapp/static/css/plugins/iCheck/green@2x.png user/guns-admin/src/main/webapp/static/css/plugins/images/sprite-skin-flat.png user/guns-admin/src/main/webapp/static/css/plugins/validate/bootstrapValidator.min.css user/guns-admin/src/main/webapp/static/css/plugins/webuploader/webuploader.css user/guns-admin/src/main/webapp/static/css/plugins/ztree/demo.css user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_close.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/1_open.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/2.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/3.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/4.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/5.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/6.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/7.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/8.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/diy/9.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/line_conn.gif user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/loading.gif user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.gif user/guns-admin/src/main/webapp/static/css/plugins/ztree/img/zTreeStandard.png user/guns-admin/src/main/webapp/static/css/plugins/ztree/zTreeStyle.css user/guns-admin/src/main/webapp/static/css/style.css user/guns-admin/src/main/webapp/static/favicon.ico user/guns-admin/src/main/webapp/static/fonts/FontAwesome.otf user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.eot user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.svg user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.ttf user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff user/guns-admin/src/main/webapp/static/fonts/fontawesome-webfont.woff2 user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.eot user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.svg user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.ttf user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff user/guns-admin/src/main/webapp/static/fonts/glyphicons-halflings-regular.woff2 user/guns-admin/src/main/webapp/static/img/bg.png user/guns-admin/src/main/webapp/static/img/boy.gif user/guns-admin/src/main/webapp/static/img/girl.gif user/guns-admin/src/main/webapp/static/img/icons.png user/guns-admin/src/main/webapp/static/img/loading-upload.gif user/guns-admin/src/main/webapp/static/img/locked.png user/guns-admin/src/main/webapp/static/img/user.png user/guns-admin/src/main/webapp/static/js/bootstrap.min.js user/guns-admin/src/main/webapp/static/js/common/DateUtils.js user/guns-admin/src/main/webapp/static/js/common/Feng.js user/guns-admin/src/main/webapp/static/js/common/ajax-object.js user/guns-admin/src/main/webapp/static/js/common/bootstrap-table-object.js user/guns-admin/src/main/webapp/static/js/common/select-list-object.js user/guns-admin/src/main/webapp/static/js/common/tree-table-object.js user/guns-admin/src/main/webapp/static/js/common/web-upload-object.js user/guns-admin/src/main/webapp/static/js/common/ztree-object.js user/guns-admin/src/main/webapp/static/js/contabs.js user/guns-admin/src/main/webapp/static/js/content.js user/guns-admin/src/main/webapp/static/js/hplus.js user/guns-admin/src/main/webapp/static/js/jquery.min.js user/guns-admin/src/main/webapp/static/js/jquery.min.map user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table-mobile.min.js user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/bootstrap-table.min.js user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.js user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-table/locale/bootstrap-table-zh-CN.min.js user/guns-admin/src/main/webapp/static/js/plugins/bootstrap-treetable/bootstrap-treetable.js user/guns-admin/src/main/webapp/static/js/plugins/chosen/chosen.jquery.js user/guns-admin/src/main/webapp/static/js/plugins/iCheck/icheck.min.js user/guns-admin/src/main/webapp/static/js/plugins/laydate/laydate.js user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.eot user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.svg user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.ttf user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/font/iconfont.woff user/guns-admin/src/main/webapp/static/js/plugins/laydate/theme/default/laydate.css user/guns-admin/src/main/webapp/static/js/plugins/layer/layer.js user/guns-admin/src/main/webapp/static/js/plugins/layer/mobile/layer.js user/guns-admin/src/main/webapp/static/js/plugins/layer/mobile/need/layer.css user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon-ext.png user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/icon.png user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/layer.css user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-0.gif user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-1.gif user/guns-admin/src/main/webapp/static/js/plugins/layer/theme/default/loading-2.gif user/guns-admin/src/main/webapp/static/js/plugins/metisMenu/jquery.metisMenu.js user/guns-admin/src/main/webapp/static/js/plugins/pace/pace.min.js user/guns-admin/src/main/webapp/static/js/plugins/slimscroll/jquery.slimscroll.min.js user/guns-admin/src/main/webapp/static/js/plugins/validate/additional-methods.min.js user/guns-admin/src/main/webapp/static/js/plugins/validate/bootstrapValidator.min.js user/guns-admin/src/main/webapp/static/js/plugins/validate/zh_CN.js user/guns-admin/src/main/webapp/static/js/plugins/wangEditor/wangEditor.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/Uploader.swf user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.css user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.custom.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.fis.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.flashonly.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.html5only.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.noimage.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.nolog.min.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.js user/guns-admin/src/main/webapp/static/js/plugins/webuploader/webuploader.withoutimage.min.js user/guns-admin/src/main/webapp/static/js/plugins/ztree/jquery.ztree.all.min.js user/guns-admin/src/main/webapp/static/modular/code/gen.js user/guns-admin/src/main/webapp/static/modular/flowable/expense/expense.js user/guns-admin/src/main/webapp/static/modular/flowable/expense/expense_info.js user/guns-admin/src/main/webapp/static/modular/flowable/process/process.js user/guns-admin/src/main/webapp/static/modular/flowable/process/process_info.js user/guns-admin/src/main/webapp/static/modular/system/code/code.js user/guns-admin/src/main/webapp/static/modular/system/dept/dept.js user/guns-admin/src/main/webapp/static/modular/system/dept/dept_info.js user/guns-admin/src/main/webapp/static/modular/system/dict/dict.js user/guns-admin/src/main/webapp/static/modular/system/dict/dict_info.js user/guns-admin/src/main/webapp/static/modular/system/log/log.js user/guns-admin/src/main/webapp/static/modular/system/log/login_log.js user/guns-admin/src/main/webapp/static/modular/system/menu/menu.js user/guns-admin/src/main/webapp/static/modular/system/menu/menu_info.js user/guns-admin/src/main/webapp/static/modular/system/notice/notice.js user/guns-admin/src/main/webapp/static/modular/system/notice/notice_info.js user/guns-admin/src/main/webapp/static/modular/system/role/role.js user/guns-admin/src/main/webapp/static/modular/system/role/role_info.js user/guns-admin/src/main/webapp/static/modular/system/user/user.js user/guns-admin/src/main/webapp/static/modular/system/user/user_info.js user/guns-core/pom.xml user/guns-core/src/main/java/com/supersavedriving/user/core/CoreFlag.java user/guns-core/src/main/java/com/supersavedriving/user/core/aop/BaseControllerExceptionHandler.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/BaseController.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/GlobalController.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/controller/GunsErrorView.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/ErrorTip.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/SuccessTip.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/tips/Tip.java user/guns-core/src/main/java/com/supersavedriving/user/core/base/warpper/BaseControllerWarpper.java user/guns-core/src/main/java/com/supersavedriving/user/core/cache/BaseCacheFactory.java user/guns-core/src/main/java/com/supersavedriving/user/core/cache/CacheKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/cache/EhcacheFactory.java user/guns-core/src/main/java/com/supersavedriving/user/core/cache/ICache.java user/guns-core/src/main/java/com/supersavedriving/user/core/cache/ILoader.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultFastjsonConfig.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultMultiConfig.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultProperties.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/DefaultWebConfig.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/properties/DruidProperties.java user/guns-core/src/main/java/com/supersavedriving/user/core/config/properties/MutiDataSourceProperties.java user/guns-core/src/main/java/com/supersavedriving/user/core/constant/IsMenu.java user/guns-core/src/main/java/com/supersavedriving/user/core/datascope/DataScope.java user/guns-core/src/main/java/com/supersavedriving/user/core/datascope/DataScopeInterceptor.java user/guns-core/src/main/java/com/supersavedriving/user/core/db/Db.java user/guns-core/src/main/java/com/supersavedriving/user/core/exception/GunsException.java user/guns-core/src/main/java/com/supersavedriving/user/core/exception/GunsExceptionEnum.java user/guns-core/src/main/java/com/supersavedriving/user/core/exception/ServiceExceptionEnum.java user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/DataSourceContextHolder.java user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/DynamicDataSource.java user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/annotion/DataSource.java user/guns-core/src/main/java/com/supersavedriving/user/core/mutidatasource/aop/MultiSourceExAop.java user/guns-core/src/main/java/com/supersavedriving/user/core/node/MenuNode.java user/guns-core/src/main/java/com/supersavedriving/user/core/node/ZTreeNode.java user/guns-core/src/main/java/com/supersavedriving/user/core/page/PageBT.java user/guns-core/src/main/java/com/supersavedriving/user/core/page/PageInfoBT.java user/guns-core/src/main/java/com/supersavedriving/user/core/qr/ImgQrTool.java user/guns-core/src/main/java/com/supersavedriving/user/core/qr/MatrixToImageConfig.java user/guns-core/src/main/java/com/supersavedriving/user/core/qr/MatrixToImageWriter.java user/guns-core/src/main/java/com/supersavedriving/user/core/qr/QrImage.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/BasicType.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/BeanKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/ClassKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/CollectionKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/DateTime.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/DateTimeKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/HexKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/HttpKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/ObjectKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/PageKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/StrKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/WafKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/WafRequestWrapper.java user/guns-core/src/main/java/com/supersavedriving/user/core/support/exception/ToolBoxException.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/Convert.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/DateUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/FileUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/HttpSessionHolder.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/IdGenerator.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/MD5Util.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/NumUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/PingYinUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/RenderUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/ResKit.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/SimpleContrast.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/SpringContextHolder.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/SqlUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/util/ToolUtil.java user/guns-core/src/main/java/com/supersavedriving/user/core/xss/XssFilter.java user/guns-core/src/main/java/com/supersavedriving/user/core/xss/XssHttpServletRequestWrapper.java user/guns-core/src/main/resources/META-INF/spring.factories user/guns-core/src/main/resources/default-config.properties user/guns-generator/pom.xml user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/GunsCodeGenerator.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/AbstractGeneratorConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/GunsGeneratorConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/config/WebGeneratorConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/action/model/GenQo.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/SimpleTemplateEngine.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/base/AbstractTemplateEngine.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/base/GunsTemplateEngine.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ContextConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ControllerConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/DaoConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/Menu.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/PageConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/ServiceConfig.java user/guns-generator/src/main/java/com/supersavedriving/user/generator/engine/config/SqlConfig.java user/guns-generator/src/main/resources/gunsTemplate/advanced/Controller.java.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/menu_sql.sql.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/page.html.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/page.js.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/page_add.html.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/page_edit.html.btl user/guns-generator/src/main/resources/gunsTemplate/advanced/page_info.js.btl user/pom.xml