From b86860da8d45a55f51e127512598b38926606285 Mon Sep 17 00:00:00 2001 From: Xiang Silian Date: Thu, 25 Dec 2025 09:57:56 +0800 Subject: [PATCH] save code --- .gitignore | 7 + README.en.md | 36 + README.md | 39 + digital-application/pom.xml | 188 ++ .../application/DigitalApplication.java | 53 + .../ScheduleTask/ClothTaskExecutor.java | 38 + .../ScheduleTask/ClothTaskService.java | 168 ++ .../ScheduleTask/FigureTaskExecutor.java | 39 + .../ScheduleTask/FigureTaskService.java | 160 ++ .../ScheduleTask/HairTaskExecutor.java | 38 + .../ScheduleTask/HairTaskService.java | 224 ++ .../ScheduleTask/UnderwearTaskExecutor.java | 39 + .../ScheduleTask/UnderwearTaskService.java | 160 ++ .../controller/DigitalClothController.java | 399 ++++ .../controller/TjSwapHairController.java | 112 + .../application/dto/AddRoomClothDTO.java | 15 + .../digital/application/dto/AddRoomDTO.java | 19 + .../digital/application/dto/AddSuitDTO.java | 18 + .../application/dto/AddWardrobeDTO.java | 18 + .../application/dto/BatchDelHistoryDTO.java | 13 + .../digital/application/dto/BuyLinksDTO.java | 19 + .../digital/application/dto/CallBackDTO.java | 18 + .../application/dto/CrawlerPictureDTO.java | 8 + .../digital/application/dto/DelRoomDTO.java | 12 + .../application/dto/DeleteClothDTO.java | 12 + .../digital/application/dto/GetModelDTO.java | 12 + .../application/dto/GetRoomClothListDTO.java | 17 + .../application/dto/GetRoomListDTO.java | 12 + .../digital/application/dto/LoginDTO.java | 14 + .../application/dto/PhoneLoginDTO.java | 24 + .../application/dto/QueryClothTypeDTO.java | 21 + .../digital/application/dto/SmsLoginDTO.java | 15 + .../application/dto/SubmitContactInfoDTO.java | 25 + .../application/dto/TrainTaskCallbackDTO.java | 20 + .../application/dto/TryOnCallBackDTO.java | 21 + .../digital/application/dto/TryOnDTO.java | 25 + .../digital/application/dto/UnJoinDTO.java | 15 + .../digital/application/dto/UnTryOnDTO.java | 14 + .../application/dto/UpdateRoomDTO.java | 17 + .../application/dto/UploadClothDTO.java | 23 + .../application/dto/UserHistoryMap.java | 21 + .../dto/tjHair/GetHairDataDTO.java | 22 + .../tjHair/GetSwapHairHistoryByTaskIdDTO.java | 12 + .../application/emun/LiveStatusEnum.java | 31 + .../digital/application/emun/ReplySource.java | 25 + .../digital/application/emun/ReplyType.java | 21 + .../application/emun/SortTypeEnum.java | 49 + .../application/emun/StatusTypeEnum.java | 56 + .../java/digital/application/emun/Type.java | 31 + .../digital/application/emun/TypeEnum.java | 23 + .../application/entity/SysContact.java | 94 + .../digital/application/entity/SysFile.java | 168 ++ .../application/entity/SysHistory.java | 70 + .../digital/application/entity/SysRoom.java | 58 + .../application/entity/SysRoomCloth.java | 56 + .../application/entity/SysTaskQueue.java | 73 + .../application/entity/SysWhiteUser.java | 52 + .../application/mapper/MwTrainTaskMapper.java | 14 + .../application/mapper/SysContactMapper.java | 8 + .../application/mapper/SysFileMapper.java | 24 + .../application/mapper/SysHistoryMapper.java | 22 + .../mapper/SysRoomClothMapper.java | 9 + .../application/mapper/SysRoomMapper.java | 9 + .../mapper/SysTaskQueueMapper.java | 8 + .../mapper/SysWhiteUserMapper.java | 9 + .../mapper/xml/MwTrainTaskMapper.xml | 5 + .../mapper/xml/SysContactMapper.xml | 5 + .../application/mapper/xml/SysFileMapper.xml | 16 + .../mapper/xml/SysHistoryMapper.xml | 46 + .../mapper/xml/SysRoomClothMapper.xml | 6 + .../application/mapper/xml/SysRoomMapper.xml | 6 + .../mapper/xml/SysTaskQueueMapper.xml | 4 + .../mapper/xml/SysWhiteUserMapper.xml | 6 + .../application/service/AsyncService.java | 183 ++ .../service/IMwTrainTaskService.java | 43 + .../service/ISysContactService.java | 18 + .../application/service/ISysFileService.java | 151 ++ .../service/SysHistoryService.java | 8 + .../application/service/SysRoomService.java | 64 + .../service/SysTaskQueueService.java | 9 + .../service/impl/MwTrainTaskServiceImpl.java | 218 ++ .../service/impl/SysContactServiceImpl.java | 37 + .../service/impl/SysFileServiceImpl.java | 1955 +++++++++++++++++ .../service/impl/SysHistoryServiceImpl.java | 13 + .../service/impl/SysRoomServiceImpl.java | 199 ++ .../service/impl/SysTaskQueueServiceImpl.java | 15 + .../digital/application/utils/AudioUtil.java | 120 + .../application/utils/AuthInterceptor.java | 55 + .../utils/CloudStorageService.java | 116 + .../application/utils/CommonUtils.java | 41 + .../digital/application/utils/FileUtils.java | 57 + .../digital/application/utils/ImageUtils.java | 64 + .../digital/application/utils/LiveUtils.java | 61 + .../utils/TencentCloudApiUtils.java | 84 + .../digital/application/utils/TimeUtils.java | 78 + .../digital/application/utils/VideoUtil.java | 78 + .../digital/application/utils/WebConfig.java | 30 + .../application/vo/CrawlerPictureVO.java | 17 + .../application/vo/GetModelListVO.java | 18 + .../digital/application/vo/GetRoomListVO.java | 26 + .../application/vo/GetSwapHairHistoryVO.java | 23 + .../application/vo/GetTryOnHistoryVO.java | 32 + .../vo/GetUploadBackgroundListVO.java | 18 + .../application/vo/LoginUserInfoVO.java | 31 + .../application/vo/QueryClothTypeListVO.java | 31 + .../digital/application/vo/StartDetailVO.java | 23 + .../application/vo/UploadFileClothVO.java | 18 + .../application/vo/tjHair/TjHairListVO.java | 18 + .../src/main/resources/application-dev.yml | 216 ++ .../src/main/resources/application-prod.yml | 216 ++ .../src/main/resources/application.yml | 5 + .../src/main/resources/banner.txt | 16 + .../src/main/resources/logback-spring.xml | 109 + digital-common/digital-base/pom.xml | 63 + .../digital/base/annotation/AutoDict.java | 24 + .../java/digital/base/annotation/AutoLog.java | 47 + .../digital/base/annotation/AutoLowApp.java | 34 + .../java/digital/base/annotation/Dict.java | 43 + .../digital/base/annotation/OnlineAuth.java | 21 + .../base/annotation/PermissionData.java | 27 + .../base/annotation/RabbitComponent.java | 24 + .../digital/base/constant/CacheConstant.java | 103 + .../digital/base/constant/CommonConstant.java | 391 ++++ .../base/constant/CommonSendStatus.java | 37 + .../base/constant/DataBaseConstant.java | 156 ++ .../digital/base/constant/DictConstants.java | 82 + .../constant/Face3dSeverHTTPConstant.java | 63 + .../base/constant/FillRuleConstant.java | 25 + .../base/constant/GlobalConstants.java | 23 + .../base/constant/LanguageTypeConstants.java | 55 + .../digital/base/constant/RoleConstant.java | 24 + .../base/constant/ServiceNameConstants.java | 42 + .../ShortVideoOfflineComConstant.java | 74 + .../digital/base/constant/SymbolConstant.java | 89 + .../base/constant/UserFileConstant.java | 62 + .../digital/base/constant/VideoConstant.java | 35 + .../digital/base/constant/VxeSocketConst.java | 33 + .../digital/base/constant/WebsocketConst.java | 61 + .../base/constant/ZitaCommonConstant.java | 64 + .../java/digital/base/enums/CgformEnum.java | 151 ++ .../java/digital/base/enums/FileTypeEnum.java | 58 + .../digital/base/enums/FileTypeKSFEnum.java | 74 + .../digital/base/enums/LowAppAopEnum.java | 24 + .../java/digital/base/enums/ModuleType.java | 19 + .../digital/base/enums/OperateTypeEnum.java | 95 + .../digital/base/enums/SMCodeMessage.java | 15 + .../base/enums/SentinelErrorInfoEnum.java | 108 + .../java/digital/base/enums/UrlMatchEnum.java | 66 + .../java/digital/base/enums/YesOrNoEnum.java | 41 + .../base/handler/IFillRuleHandler.java | 22 + .../main/java/digital/base/vo/LoginUser.java | 92 + .../src/main/java/digital/base/vo/Result.java | 241 ++ .../base/vo/SysPermissionDataRuleModel.java | 144 ++ digital-common/digital-bean/pom.xml | 64 + .../main/java/digital/bean/jeecg/BaseMap.java | 139 ++ .../digital/bean/jeecg/dto/FileDownDTO.java | 31 + .../digital/bean/jeecg/dto/FileUploadDTO.java | 56 + .../java/digital/bean/jeecg/dto/LogDTO.java | 85 + .../digital/bean/jeecg/dto/OnlineAuthDTO.java | 42 + .../bean/jeecg/dto/message/BusMessageDTO.java | 44 + .../dto/message/BusTemplateMessageDTO.java | 46 + .../bean/jeecg/dto/message/MessageDTO.java | 75 + .../bean/jeecg/dto/message/TemplateDTO.java | 38 + .../jeecg/dto/message/TemplateMessageDTO.java | 50 + .../bean/jeecg/entity/JeecgEntity.java | 66 + .../digital/bean/jeecg/vo/ComboModel.java | 52 + .../java/digital/bean/jeecg/vo/DictModel.java | 53 + .../digital/bean/jeecg/vo/DictModelMany.java | 20 + .../java/digital/bean/jeecg/vo/DictQuery.java | 36 + .../bean/jeecg/vo/DynamicDataSourceModel.java | 57 + .../bean/jeecg/vo/SelectTreeModel.java | 32 + .../bean/jeecg/vo/SysCategoryModel.java | 58 + .../digital/bean/jeecg/vo/SysDepartModel.java | 177 ++ .../main/java/digital/bean/task/DpUser.java | 249 +++ .../java/digital/bean/task/MwTrainTask.java | 81 + digital-common/digital-config/pom.xml | 232 ++ .../java/digital/config/AutoPoiConfig.java | 28 + .../java/digital/config/CommonConfig.java | 28 + .../digital/config/CorsFilterCondition.java | 25 + .../main/java/digital/config/DruidConfig.java | 85 + .../java/digital/config/JeecgBaseConfig.java | 52 + .../digital/config/JeecgCloudCondition.java | 25 + .../java/digital/config/MyLocaleResolver.java | 31 + .../digital/config/RestTemplateConfig.java | 31 + .../java/digital/config/StaticConfig.java | 38 + .../java/digital/config/Swagger2Config.java | 184 ++ .../config/ThreadPoolConfiguration.java | 23 + .../digital/config/WebMvcConfiguration.java | 157 ++ .../java/digital/config/WebSocketConfig.java | 22 + .../digital/config/filter/FilterConfig.java | 25 + .../digital/config/filter/MyAesFilter.java | 116 + .../digital/config/filter/RequestWrapper.java | 145 ++ .../config/filter/ResponseWrapper.java | 76 + .../digital/config/mns/MnsConfiguration.java | 42 + .../mqtoken/TransmitUserTokenFilter.java | 45 + .../config/mqtoken/UserTokenContext.java | 31 + .../config/mybatis/JeecgTenantParser.java | 129 ++ .../config/mybatis/MybatisInterceptor.java | 182 ++ .../config/mybatis/MybatisPlusSaasConfig.java | 112 + .../digital/config/mybatis/TenantContext.java | 25 + .../java/digital/config/oss/MinioConfig.java | 40 + .../digital/config/oss/OssConfiguration.java | 39 + .../java/digital/config/shiro/JwtToken.java | 28 + .../filters/CustomShiroFilterFactoryBean.java | 77 + .../config/shiro/filters/JwtFilter.java | 110 + .../shiro/filters/ResourceCheckFilter.java | 68 + .../interceptor/SignAuthConfiguration.java | 27 + .../sign/interceptor/SignAuthInterceptor.java | 78 + .../BodyReaderHttpServletRequestWrapper.java | 107 + .../digital/config/sign/util/HttpUtils.java | 185 ++ .../digital/config/sign/util/SignUtil.java | 59 + .../main/java/digital/config/vo/Shiro.java | 18 + digital-common/digital-util/pom.xml | 124 ++ .../annotation/SensitiveDecode.java | 20 + .../annotation/SensitiveEncode.java | 20 + .../annotation/SensitiveField.java | 22 + .../aspect/SensitiveDataAspect.java | 79 + .../desensitization/enums/ResultTypeEnum.java | 52 + .../desensitization/enums/SensitiveEnum.java | 55 + .../util/SensitiveInfoUtil.java | 362 +++ .../util/encryption/AesEncryptUtil.java | 126 ++ .../util/encryption/EncryptedString.java | 22 + .../util/es/JeecgElasticsearchTemplate.java | 551 +++++ .../digital/util/es/QueryStringBuilder.java | 98 + .../util/exception/JeecgBoot401Exception.java | 23 + .../util/exception/JeecgBootException.java | 23 + .../exception/JeecgBootExceptionHandler.java | 212 ++ .../util/exception/JeecgCloudException.java | 15 + .../digital/util/filter/FileTypeFilter.java | 164 ++ .../digital/util/filter/StrAttackFilter.java | 25 + .../java/digital/util/oss/OssBootUtil.java | 655 ++++++ .../util/oss/OssUploadWithThirdPartySTS.java | 22 + .../main/java/digital/util/oss/UserUtil.java | 20 + .../AbstractQueryBlackListHandler.java | 174 ++ .../digital/util/security/SecurityTools.java | 82 + .../util/security/entity/MyKeyPair.java | 13 + .../util/security/entity/SecurityReq.java | 15 + .../util/security/entity/SecurityResp.java | 14 + .../util/security/entity/SecuritySignReq.java | 13 + .../security/entity/SecuritySignResp.java | 14 + .../util/superSearch/ObjectParseUtil.java | 60 + .../util/superSearch/QueryRuleEnum.java | 71 + .../digital/util/superSearch/QueryRuleVo.java | 15 + .../java/digital/util/util/BrowserType.java | 13 + .../java/digital/util/util/BrowserUtils.java | 211 ++ .../java/digital/util/util/CommonUtils.java | 349 +++ .../java/digital/util/util/DateUtils.java | 674 ++++++ .../digital/util/util/DigitalPersonUtils.java | 34 + .../java/digital/util/util/DySmsEnum.java | 87 + .../java/digital/util/util/DySmsHelper.java | 126 ++ .../java/digital/util/util/EmailUtils.java | 23 + .../java/digital/util/util/FillRuleUtil.java | 57 + .../java/digital/util/util/HTMLUtils.java | 32 + .../digital/util/util/ImportExcelUtil.java | 97 + .../main/java/digital/util/util/IpUtils.java | 61 + .../util/util/JeecgDataAutorUtils.java | 106 + .../digital/util/util/JeecgRedisUtil.java | 613 ++++++ .../main/java/digital/util/util/JwtUtil.java | 261 +++ .../util/util/ListToStringConverter.java | 16 + .../main/java/digital/util/util/Md5Util.java | 49 + .../java/digital/util/util/MinioUtil.java | 222 ++ .../java/digital/util/util/MyClassLoader.java | 106 + .../java/digital/util/util/PasswordUtil.java | 191 ++ .../digital/util/util/PathMatcherUtil.java | 97 + .../main/java/digital/util/util/PmsUtil.java | 65 + .../digital/util/util/ProvinceCityArea.java | 199 ++ .../java/digital/util/util/ReflectHelper.java | 255 +++ .../digital/util/util/RestDesformUtil.java | 122 + .../main/java/digital/util/util/RestUtil.java | 328 +++ .../util/util/SpringContextHolder.java | 81 + .../digital/util/util/SpringContextUtils.java | 108 + .../digital/util/util/SqlInjectionUtil.java | 172 ++ .../digital/util/util/SysAnnmentTypeEnum.java | 71 + .../digital/util/util/SysUserCacheInfo.java | 70 + .../java/digital/util/util/UUIDGenerator.java | 96 + .../digital/util/util/YouBianCodeUtil.java | 175 ++ .../java/digital/util/util/oConvertUtils.java | 689 ++++++ digital-common/pom.xml | 25 + digital-system/pom.xml | 85 + .../jeecg/controller/SystemAPIController.java | 697 ++++++ .../digital/system/jeecg/group/CommonAPI.java | 134 ++ .../system/jeecg/group/api/ISysBaseAPI.java | 592 +++++ .../factory/SysBaseAPIFallbackFactory.java | 21 + .../api/fallback/SysBaseAPIFallback.java | 324 +++ .../system/jeecg/group/base/ISysBaseAPI.java | 387 ++++ .../base/controller/JeecgController.java | 208 ++ .../group/base/mapper/BaseCommonMapper.java | 22 + .../base/mapper/xml/BaseCommonMapper.xml | 26 + .../group/base/service/BaseCommonService.java | 38 + .../group/base/service/JeecgService.java | 12 + .../service/impl/BaseCommonServiceImpl.java | 89 + .../base/service/impl/JeecgServiceImpl.java | 18 + .../jeecg/group/config/AutoPoiDictConfig.java | 77 + .../jeecg/group/config/RedisConfig.java | 140 ++ .../jeecg/group/config/ShiroConfig.java | 303 +++ .../system/jeecg/group/config/ShiroRealm.java | 204 ++ .../group/ngalain/aop/LogRecordAspect.java | 46 + .../ngalain/controller/NgAlainController.java | 86 + .../group/ngalain/service/NgAlainService.java | 40 + .../service/impl/NgAlainServiceImpl.java | 189 ++ .../jeecg/group/query/MatchTypeEnum.java | 48 + .../jeecg/group/query/QueryCondition.java | 73 + .../jeecg/group/query/QueryGenerator.java | 1167 ++++++++++ .../jeecg/group/query/QueryRuleEnum.java | 88 + .../group/redis/client/JeecgRedisClient.java | 35 + .../redis/listener/JeecgRedisListener.java | 19 + .../group/redis/receiver/RedisReceiver.java | 33 + .../redis/writer/JeecgRedisCacheWriter.java | 250 +++ .../system/jeecg/group/util/TokenUtils.java | 123 ++ .../group/util/aspect/AutoLogAspect.java | 296 +++ .../group/util/aspect/ContactFeiShuUtils.java | 37 + .../jeecg/group/util/aspect/DictAspect.java | 454 ++++ .../jeecg/group/util/aspect/FeiShuUtils.java | 38 + .../util/aspect/PermissionDataAspect.java | 135 ++ .../group/util/db/DataSourceCachePool.java | 93 + .../jeecg/group/util/db/DbTypeUtils.java | 122 + .../jeecg/group/util/db/DynamicDBUtil.java | 342 +++ .../group/util/db/FreemarkerParseFactory.java | 182 ++ .../group/util/db/RoleIndexConfigEnum.java | 103 + .../controller/SysMessageController.java | 135 ++ .../SysMessageTemplateController.java | 160 ++ .../jeecg/message/entity/MsgParams.java | 36 + .../jeecg/message/entity/SysMessage.java | 79 + .../message/entity/SysMessageTemplate.java | 47 + .../jeecg/message/handle/ISendMsgHandle.java | 17 + .../handle/enums/SendMsgStatusEnum.java | 27 + .../message/handle/enums/SendMsgTypeEnum.java | 66 + .../handle/impl/EmailSendMsgHandle.java | 44 + .../message/handle/impl/SmsSendMsgHandle.java | 19 + .../handle/impl/SystemSendMsgHandle.java | 24 + .../message/handle/impl/WxSendMsgHandle.java | 19 + .../message/mapper/SysMessageMapper.java | 14 + .../mapper/SysMessageTemplateMapper.java | 25 + .../message/mapper/xml/ChUserFileMapper.xml | 5 + .../mapper/xml/SysMessageTemplateMapper.xml | 5 + .../message/service/ISysMessageService.java | 15 + .../service/ISysMessageTemplateService.java | 23 + .../service/impl/SysMessageServiceImpl.java | 19 + .../impl/SysMessageTemplateServiceImpl.java | 30 + .../jeecg/message/util/PushMsgUtil.java | 79 + .../message/websocket/SocketHandler.java | 38 + .../websocket/TestSocketController.java | 52 + .../jeecg/message/websocket/WebSocket.java | 158 ++ .../controller/ActuatorRedisController.java | 129 ++ .../jeecg/monitor/domain/RedisInfo.java | 141 ++ .../exception/RedisConnectException.java | 15 + .../jeecg/monitor/service/RedisService.java | 48 + .../service/impl/MailHealthIndicator.java | 31 + .../service/impl/RedisServiceImpl.java | 117 + .../oss/controller/OSSFileController.java | 95 + .../system/jeecg/oss/entity/OSSFile.java | 24 + .../jeecg/oss/mapper/OSSFileMapper.java | 8 + .../jeecg/oss/service/IOSSFileService.java | 15 + .../oss/service/impl/OSSFileServiceImpl.java | 41 + .../jeecg/system/DTO/UserRegisterDTO.java | 23 + .../controller/DuplicateCheckController.java | 87 + .../controller/SysCategoryController.java | 515 +++++ .../controller/SysCheckRuleController.java | 186 ++ .../controller/SysDataLogController.java | 96 + .../controller/SysDataSourceController.java | 216 ++ .../system/controller/SysDictController.java | 629 ++++++ .../controller/SysDictItemController.java | 178 ++ .../controller/SysFillRuleController.java | 212 ++ .../controller/SysGatewayRouteController.java | 76 + .../system/controller/SysLogController.java | 115 + .../controller/SysPermissionController.java | 936 ++++++++ .../controller/SysPositionController.java | 282 +++ .../system/controller/SysRoleController.java | 402 ++++ .../controller/SysRoleIndexController.java | 166 ++ .../controller/SysTenantController.java | 232 ++ .../controller/SysUploadController.java | 69 + .../controller/SysUserAgentController.java | 257 +++ .../controller/SysUserOnlineController.java | 105 + .../controller/SysVersionController.java | 177 ++ .../jeecg/system/entity/SysAnnouncement.java | 150 ++ .../system/entity/SysAnnouncementSend.java | 66 + .../jeecg/system/entity/SysCategory.java | 87 + .../jeecg/system/entity/SysCheckRule.java | 88 + .../jeecg/system/entity/SysDataLog.java | 73 + .../jeecg/system/entity/SysDataSource.java | 120 + .../system/jeecg/system/entity/SysDepart.java | 193 ++ .../system/entity/SysDepartPermission.java | 58 + .../jeecg/system/entity/SysDepartRole.java | 90 + .../entity/SysDepartRolePermission.java | 78 + .../system/entity/SysDepartRoleUser.java | 53 + .../system/jeecg/system/entity/SysDict.java | 84 + .../jeecg/system/entity/SysDictItem.java | 80 + .../jeecg/system/entity/SysFillRule.java | 86 + .../jeecg/system/entity/SysGatewayRoute.java | 133 ++ .../system/jeecg/system/entity/SysLog.java | 113 + .../jeecg/system/entity/SysPermission.java | 200 ++ .../system/entity/SysPermissionDataRule.java | 82 + .../jeecg/system/entity/SysPosition.java | 88 + .../system/jeecg/system/entity/SysRole.java | 79 + .../jeecg/system/entity/SysRoleIndex.java | 92 + .../system/entity/SysRolePermission.java | 70 + .../system/jeecg/system/entity/SysTenant.java | 66 + .../jeecg/system/entity/SysThirdAccount.java | 106 + .../system/jeecg/system/entity/SysUser.java | 116 + .../jeecg/system/entity/SysUserAgent.java | 102 + .../jeecg/system/entity/SysUserDepart.java | 44 + .../jeecg/system/entity/SysUserRole.java | 48 + .../jeecg/system/entity/SysVersion.java | 80 + .../jeecg/system/mapper/DpUserMapper.java | 14 + .../system/mapper/SysAnnouncementMapper.java | 28 + .../mapper/SysAnnouncementSendMapper.java | 36 + .../system/mapper/SysCategoryMapper.java | 39 + .../system/mapper/SysCheckRuleMapper.java | 14 + .../jeecg/system/mapper/SysDataLogMapper.java | 21 + .../system/mapper/SysDataSourceMapper.java | 14 + .../jeecg/system/mapper/SysDepartMapper.java | 103 + .../mapper/SysDepartPermissionMapper.java | 14 + .../system/mapper/SysDepartRoleMapper.java | 24 + .../mapper/SysDepartRolePermissionMapper.java | 14 + .../mapper/SysDepartRoleUserMapper.java | 14 + .../system/mapper/SysDictItemMapper.java | 34 + .../jeecg/system/mapper/SysDictMapper.java | 300 +++ .../system/mapper/SysFillRuleMapper.java | 14 + .../system/mapper/SysGatewayRouteMapper.java | 14 + .../jeecg/system/mapper/SysLogMapper.java | 63 + .../mapper/SysPermissionDataRuleMapper.java | 28 + .../system/mapper/SysPermissionMapper.java | 66 + .../system/mapper/SysPositionMapper.java | 14 + .../system/mapper/SysRoleIndexMapper.java | 14 + .../jeecg/system/mapper/SysRoleMapper.java | 36 + .../mapper/SysRolePermissionMapper.java | 16 + .../jeecg/system/mapper/SysTenantMapper.java | 12 + .../system/mapper/SysThirdAccountMapper.java | 26 + .../system/mapper/SysUserAgentMapper.java | 14 + .../system/mapper/SysUserDepartMapper.java | 45 + .../jeecg/system/mapper/SysUserMapper.java | 179 ++ .../system/mapper/SysUserRoleMapper.java | 38 + .../jeecg/system/mapper/SysVersionMapper.java | 17 + .../jeecg/system/mapper/xml/DpUserMapper.xml | 5 + .../mapper/xml/SysAnnouncementMapper.xml | 41 + .../mapper/xml/SysAnnouncementSendMapper.xml | 68 + .../system/mapper/xml/SysCategoryMapper.xml | 21 + .../system/mapper/xml/SysCheckRuleMapper.xml | 5 + .../system/mapper/xml/SysDataSourceMapper.xml | 5 + .../system/mapper/xml/SysDepartMapper.xml | 64 + .../mapper/xml/SysDepartPermissionMapper.xml | 5 + .../system/mapper/xml/SysDepartRoleMapper.xml | 16 + .../xml/SysDepartRolePermissionMapper.xml | 5 + .../mapper/xml/SysDepartRoleUserMapper.xml | 5 + .../system/mapper/xml/SysDictItemMapper.xml | 11 + .../jeecg/system/mapper/xml/SysDictMapper.xml | 235 ++ .../system/mapper/xml/SysFillRuleMapper.xml | 5 + .../mapper/xml/SysGatewayRouteMapper.xml | 5 + .../jeecg/system/mapper/xml/SysLogMapper.xml | 80 + .../xml/SysPermissionDataRuleMapper.xml | 26 + .../system/mapper/xml/SysPermissionMapper.xml | 108 + .../system/mapper/xml/SysPositionMapper.xml | 5 + .../system/mapper/xml/SysRoleIndexMapper.xml | 5 + .../system/mapper/xml/SysTenantMapper.xml | 5 + .../mapper/xml/SysThirdAccountMapper.xml | 16 + .../system/mapper/xml/SysUserAgentMapper.xml | 5 + .../system/mapper/xml/SysUserDepartMapper.xml | 41 + .../jeecg/system/mapper/xml/SysUserMapper.xml | 194 ++ .../system/mapper/xml/SysVersionMapper.xml | 5 + .../xml/UploadVideoFileManageMapper.xml | 12 + .../system/model/AnnouncementSendModel.java | 99 + .../jeecg/system/model/DepartIdModel.java | 95 + .../jeecg/system/model/DuplicateCheckVo.java | 45 + .../system/model/SysDepartTreeModel.java | 402 ++++ .../jeecg/system/model/SysDictTree.java | 96 + .../jeecg/system/model/SysLoginModel.java | 55 + .../jeecg/system/model/SysPermissionTree.java | 431 ++++ .../system/model/SysUserSysDepartModel.java | 24 + .../jeecg/system/model/ThirdLoginModel.java | 76 + .../system/jeecg/system/model/TreeModel.java | 171 ++ .../jeecg/system/model/TreeSelectModel.java | 94 + .../jeecg/system/rule/CategoryCodeRule.java | 71 + .../jeecg/system/rule/OrderNumberRule.java | 36 + .../system/jeecg/system/rule/OrgCodeRule.java | 98 + .../security/DictQueryBlackListHandler.java | 57 + .../jeecg/system/service/IDpUserService.java | 27 + .../service/ISysAnnouncementSendService.java | 35 + .../service/ISysAnnouncementService.java | 49 + .../system/service/ISysCategoryService.java | 96 + .../system/service/ISysCheckRuleService.java | 33 + .../system/service/ISysDataLogService.java | 21 + .../system/service/ISysDataSourceService.java | 14 + .../service/ISysDepartPermissionService.java | 33 + .../ISysDepartRolePermissionService.java | 21 + .../system/service/ISysDepartRoleService.java | 25 + .../service/ISysDepartRoleUserService.java | 32 + .../system/service/ISysDepartService.java | 182 ++ .../system/service/ISysDictItemService.java | 25 + .../jeecg/system/service/ISysDictService.java | 279 +++ .../system/service/ISysFillRuleService.java | 14 + .../service/ISysGatewayRouteService.java | 41 + .../jeecg/system/service/ISysLogService.java | 61 + .../ISysPermissionDataRuleService.java | 59 + .../system/service/ISysPermissionService.java | 100 + .../system/service/ISysPositionService.java | 22 + .../system/service/ISysRoleIndexService.java | 14 + .../service/ISysRolePermissionService.java | 33 + .../jeecg/system/service/ISysRoleService.java | 45 + .../system/service/ISysTenantService.java | 39 + .../service/ISysThirdAccountService.java | 69 + .../system/service/ISysUserAgentService.java | 14 + .../system/service/ISysUserDepartService.java | 59 + .../system/service/ISysUserRoleService.java | 15 + .../jeecg/system/service/ISysUserService.java | 322 +++ .../system/service/ISysVersionService.java | 13 + .../system/service/IThirdAppService.java | 96 + .../service/impl/DpUserServiceImpl.java | 77 + .../service/impl/ImportFileServiceImpl.java | 28 + .../impl/SysAnnouncementSendServiceImpl.java | 37 + .../impl/SysAnnouncementServiceImpl.java | 128 ++ .../system/service/impl/SysBaseApiImpl.java | 1170 ++++++++++ .../service/impl/SysCategoryServiceImpl.java | 238 ++ .../service/impl/SysCheckRuleServiceImpl.java | 98 + .../service/impl/SysDataLogServiceImpl.java | 37 + .../impl/SysDataSourceServiceImpl.java | 18 + .../impl/SysDepartPermissionServiceImpl.java | 111 + .../SysDepartRolePermissionServiceImpl.java | 87 + .../impl/SysDepartRoleServiceImpl.java | 24 + .../impl/SysDepartRoleUserServiceImpl.java | 93 + .../service/impl/SysDepartServiceImpl.java | 682 ++++++ .../service/impl/SysDictItemServiceImpl.java | 30 + .../service/impl/SysDictServiceImpl.java | 449 ++++ .../service/impl/SysFillRuleServiceImpl.java | 18 + .../impl/SysGatewayRouteServiceImpl.java | 109 + .../service/impl/SysLogServiceImpl.java | 63 + .../impl/SysPermissionDataRuleImpl.java | 114 + .../impl/SysPermissionServiceImpl.java | 266 +++ .../service/impl/SysPositionServiceImpl.java | 26 + .../service/impl/SysRoleIndexServiceImpl.java | 18 + .../impl/SysRolePermissionServiceImpl.java | 117 + .../service/impl/SysRoleServiceImpl.java | 88 + .../service/impl/SysTenantServiceImpl.java | 60 + .../service/impl/SysUserAgentServiceImpl.java | 18 + .../impl/SysUserDepartServiceImpl.java | 184 ++ .../service/impl/SysUserRoleServiceImpl.java | 20 + .../service/impl/SysUserServiceImpl.java | 688 ++++++ .../service/impl/SysVersionServiceImpl.java | 33 + .../system/util/FindsDepartsChildrenUtil.java | 129 ++ .../jeecg/system/util/PermissionDataUtil.java | 97 + .../jeecg/system/util/RandImageUtil.java | 148 ++ .../jeecg/system/util/SecurityUtil.java | 59 + .../system/jeecg/system/util/XSSUtils.java | 44 + .../jeecg/system/vo/SysDepartUsersVO.java | 37 + .../system/jeecg/system/vo/SysDictPage.java | 47 + .../system/jeecg/system/vo/SysUserDepVo.java | 15 + .../jeecg/system/vo/SysUserOnlineVO.java | 59 + .../system/jeecg/system/vo/SysUserRoleVO.java | 35 + .../system/jeecg/system/vo/SysUserVO.java | 13 + pom.xml | 427 ++++ 549 files changed, 52970 insertions(+) create mode 100644 .gitignore create mode 100644 README.en.md create mode 100644 README.md create mode 100644 digital-application/pom.xml create mode 100644 digital-application/src/main/java/digital/application/DigitalApplication.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskExecutor.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskService.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskExecutor.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskService.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/HairTaskExecutor.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/HairTaskService.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskExecutor.java create mode 100644 digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskService.java create mode 100644 digital-application/src/main/java/digital/application/controller/DigitalClothController.java create mode 100644 digital-application/src/main/java/digital/application/controller/TjSwapHairController.java create mode 100644 digital-application/src/main/java/digital/application/dto/AddRoomClothDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/AddRoomDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/AddSuitDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/AddWardrobeDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/BatchDelHistoryDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/BuyLinksDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/CallBackDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/CrawlerPictureDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/DelRoomDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/DeleteClothDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/GetModelDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/GetRoomClothListDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/GetRoomListDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/LoginDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/PhoneLoginDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/QueryClothTypeDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/SmsLoginDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/SubmitContactInfoDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/TrainTaskCallbackDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/TryOnCallBackDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/TryOnDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/UnJoinDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/UnTryOnDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/UpdateRoomDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/UploadClothDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/UserHistoryMap.java create mode 100644 digital-application/src/main/java/digital/application/dto/tjHair/GetHairDataDTO.java create mode 100644 digital-application/src/main/java/digital/application/dto/tjHair/GetSwapHairHistoryByTaskIdDTO.java create mode 100644 digital-application/src/main/java/digital/application/emun/LiveStatusEnum.java create mode 100644 digital-application/src/main/java/digital/application/emun/ReplySource.java create mode 100644 digital-application/src/main/java/digital/application/emun/ReplyType.java create mode 100644 digital-application/src/main/java/digital/application/emun/SortTypeEnum.java create mode 100644 digital-application/src/main/java/digital/application/emun/StatusTypeEnum.java create mode 100644 digital-application/src/main/java/digital/application/emun/Type.java create mode 100644 digital-application/src/main/java/digital/application/emun/TypeEnum.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysContact.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysFile.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysHistory.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysRoom.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysRoomCloth.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysTaskQueue.java create mode 100644 digital-application/src/main/java/digital/application/entity/SysWhiteUser.java create mode 100644 digital-application/src/main/java/digital/application/mapper/MwTrainTaskMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysContactMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysFileMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysHistoryMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysRoomClothMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysRoomMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysTaskQueueMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/SysWhiteUserMapper.java create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/MwTrainTaskMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysContactMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysFileMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysHistoryMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysRoomClothMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysRoomMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysTaskQueueMapper.xml create mode 100644 digital-application/src/main/java/digital/application/mapper/xml/SysWhiteUserMapper.xml create mode 100644 digital-application/src/main/java/digital/application/service/AsyncService.java create mode 100644 digital-application/src/main/java/digital/application/service/IMwTrainTaskService.java create mode 100644 digital-application/src/main/java/digital/application/service/ISysContactService.java create mode 100644 digital-application/src/main/java/digital/application/service/ISysFileService.java create mode 100644 digital-application/src/main/java/digital/application/service/SysHistoryService.java create mode 100644 digital-application/src/main/java/digital/application/service/SysRoomService.java create mode 100644 digital-application/src/main/java/digital/application/service/SysTaskQueueService.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/MwTrainTaskServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/SysContactServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/SysFileServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/SysHistoryServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/SysRoomServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/service/impl/SysTaskQueueServiceImpl.java create mode 100644 digital-application/src/main/java/digital/application/utils/AudioUtil.java create mode 100644 digital-application/src/main/java/digital/application/utils/AuthInterceptor.java create mode 100644 digital-application/src/main/java/digital/application/utils/CloudStorageService.java create mode 100644 digital-application/src/main/java/digital/application/utils/CommonUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/FileUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/ImageUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/LiveUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/TencentCloudApiUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/TimeUtils.java create mode 100644 digital-application/src/main/java/digital/application/utils/VideoUtil.java create mode 100644 digital-application/src/main/java/digital/application/utils/WebConfig.java create mode 100644 digital-application/src/main/java/digital/application/vo/CrawlerPictureVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/GetModelListVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/GetRoomListVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/GetSwapHairHistoryVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/GetTryOnHistoryVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/GetUploadBackgroundListVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/LoginUserInfoVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/QueryClothTypeListVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/StartDetailVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/UploadFileClothVO.java create mode 100644 digital-application/src/main/java/digital/application/vo/tjHair/TjHairListVO.java create mode 100644 digital-application/src/main/resources/application-dev.yml create mode 100644 digital-application/src/main/resources/application-prod.yml create mode 100644 digital-application/src/main/resources/application.yml create mode 100644 digital-application/src/main/resources/banner.txt create mode 100644 digital-application/src/main/resources/logback-spring.xml create mode 100644 digital-common/digital-base/pom.xml create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/AutoDict.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/AutoLog.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/AutoLowApp.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/Dict.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/OnlineAuth.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/PermissionData.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/annotation/RabbitComponent.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/CacheConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/CommonConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/CommonSendStatus.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/DataBaseConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/DictConstants.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/Face3dSeverHTTPConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/FillRuleConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/GlobalConstants.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/LanguageTypeConstants.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/RoleConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/ServiceNameConstants.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/ShortVideoOfflineComConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/SymbolConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/UserFileConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/VideoConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/VxeSocketConst.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/WebsocketConst.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/constant/ZitaCommonConstant.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/CgformEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/FileTypeEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/FileTypeKSFEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/LowAppAopEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/ModuleType.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/OperateTypeEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/SMCodeMessage.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/SentinelErrorInfoEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/UrlMatchEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/enums/YesOrNoEnum.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/handler/IFillRuleHandler.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/vo/LoginUser.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/vo/Result.java create mode 100644 digital-common/digital-base/src/main/java/digital/base/vo/SysPermissionDataRuleModel.java create mode 100644 digital-common/digital-bean/pom.xml create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/BaseMap.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileDownDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileUploadDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/LogDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/OnlineAuthDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusMessageDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusTemplateMessageDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/MessageDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateMessageDTO.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/entity/JeecgEntity.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/ComboModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModelMany.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictQuery.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DynamicDataSourceModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SelectTreeModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysCategoryModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysDepartModel.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/task/DpUser.java create mode 100644 digital-common/digital-bean/src/main/java/digital/bean/task/MwTrainTask.java create mode 100644 digital-common/digital-config/pom.xml create mode 100644 digital-common/digital-config/src/main/java/digital/config/AutoPoiConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/CommonConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/CorsFilterCondition.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/DruidConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/JeecgBaseConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/JeecgCloudCondition.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/MyLocaleResolver.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/RestTemplateConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/StaticConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/Swagger2Config.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/ThreadPoolConfiguration.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/WebMvcConfiguration.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/WebSocketConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/filter/FilterConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/filter/MyAesFilter.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/filter/RequestWrapper.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/filter/ResponseWrapper.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mns/MnsConfiguration.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mqtoken/TransmitUserTokenFilter.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mqtoken/UserTokenContext.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mybatis/JeecgTenantParser.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisInterceptor.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisPlusSaasConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/mybatis/TenantContext.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/oss/MinioConfig.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/oss/OssConfiguration.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/shiro/JwtToken.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/shiro/filters/CustomShiroFilterFactoryBean.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/shiro/filters/JwtFilter.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/shiro/filters/ResourceCheckFilter.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthConfiguration.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthInterceptor.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/sign/util/BodyReaderHttpServletRequestWrapper.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/sign/util/HttpUtils.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/sign/util/SignUtil.java create mode 100644 digital-common/digital-config/src/main/java/digital/config/vo/Shiro.java create mode 100644 digital-common/digital-util/pom.xml create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveDecode.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveEncode.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveField.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/aspect/SensitiveDataAspect.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/enums/ResultTypeEnum.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/enums/SensitiveEnum.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/desensitization/util/SensitiveInfoUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/encryption/AesEncryptUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/encryption/EncryptedString.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/es/JeecgElasticsearchTemplate.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/es/QueryStringBuilder.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/exception/JeecgBoot401Exception.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootException.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootExceptionHandler.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/exception/JeecgCloudException.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/filter/FileTypeFilter.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/filter/StrAttackFilter.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/oss/OssBootUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/oss/OssUploadWithThirdPartySTS.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/oss/UserUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/AbstractQueryBlackListHandler.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/SecurityTools.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/entity/MyKeyPair.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityReq.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityResp.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignReq.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignResp.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/superSearch/ObjectParseUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleEnum.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleVo.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/BrowserType.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/BrowserUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/CommonUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/DateUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/DigitalPersonUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/DySmsEnum.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/DySmsHelper.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/EmailUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/FillRuleUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/HTMLUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/ImportExcelUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/IpUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/JeecgDataAutorUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/JeecgRedisUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/JwtUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/ListToStringConverter.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/Md5Util.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/MinioUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/MyClassLoader.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/PasswordUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/PathMatcherUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/PmsUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/ProvinceCityArea.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/ReflectHelper.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/RestDesformUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/RestUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/SpringContextHolder.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/SpringContextUtils.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/SqlInjectionUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/SysAnnmentTypeEnum.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/SysUserCacheInfo.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/UUIDGenerator.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/YouBianCodeUtil.java create mode 100644 digital-common/digital-util/src/main/java/digital/util/util/oConvertUtils.java create mode 100644 digital-common/pom.xml create mode 100644 digital-system/pom.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/controller/SystemAPIController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/CommonAPI.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/api/ISysBaseAPI.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/api/factory/SysBaseAPIFallbackFactory.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/api/fallback/SysBaseAPIFallback.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/ISysBaseAPI.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/controller/JeecgController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/mapper/BaseCommonMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/mapper/xml/BaseCommonMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/service/BaseCommonService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/service/JeecgService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/BaseCommonServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/JeecgServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/config/AutoPoiDictConfig.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/config/RedisConfig.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/config/ShiroConfig.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/config/ShiroRealm.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/ngalain/aop/LogRecordAspect.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/ngalain/controller/NgAlainController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/ngalain/service/NgAlainService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/ngalain/service/impl/NgAlainServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/query/MatchTypeEnum.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/query/QueryCondition.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/query/QueryGenerator.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/query/QueryRuleEnum.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/redis/client/JeecgRedisClient.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/redis/listener/JeecgRedisListener.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/redis/receiver/RedisReceiver.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/redis/writer/JeecgRedisCacheWriter.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/TokenUtils.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/aspect/AutoLogAspect.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/aspect/ContactFeiShuUtils.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/aspect/DictAspect.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/aspect/FeiShuUtils.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/aspect/PermissionDataAspect.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/db/DataSourceCachePool.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/db/DbTypeUtils.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/db/DynamicDBUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/db/FreemarkerParseFactory.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/group/util/db/RoleIndexConfigEnum.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageTemplateController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/entity/MsgParams.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessage.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessageTemplate.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/ISendMsgHandle.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgStatusEnum.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgTypeEnum.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/impl/EmailSendMsgHandle.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SmsSendMsgHandle.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SystemSendMsgHandle.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/handle/impl/WxSendMsgHandle.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageTemplateMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/ChUserFileMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/SysMessageTemplateMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageTemplateService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageTemplateServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/util/PushMsgUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/websocket/SocketHandler.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/websocket/TestSocketController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/message/websocket/WebSocket.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/controller/ActuatorRedisController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/domain/RedisInfo.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/exception/RedisConnectException.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/service/RedisService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/MailHealthIndicator.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/RedisServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/oss/controller/OSSFileController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/oss/entity/OSSFile.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/oss/mapper/OSSFileMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/oss/service/IOSSFileService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/oss/service/impl/OSSFileServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/DTO/UserRegisterDTO.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/DuplicateCheckController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysCategoryController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysCheckRuleController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataLogController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataSourceController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictItemController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysFillRuleController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysGatewayRouteController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysLogController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysPermissionController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysPositionController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleIndexController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysTenantController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysUploadController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserAgentController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserOnlineController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/controller/SysVersionController.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncement.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncementSend.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysCategory.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysCheckRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataLog.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataSource.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepart.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartPermission.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRole.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRolePermission.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRoleUser.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDict.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysDictItem.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysFillRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysGatewayRoute.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysLog.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermission.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermissionDataRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysPosition.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysRole.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysRoleIndex.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysRolePermission.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysTenant.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysThirdAccount.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysUser.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserAgent.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserDepart.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserRole.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/entity/SysVersion.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/DpUserMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementSendMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCategoryMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCheckRuleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataLogMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataSourceMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartPermissionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRolePermissionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleUserMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictItemMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysFillRuleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysGatewayRouteMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysLogMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionDataRuleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPositionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleIndexMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRolePermissionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysTenantMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysThirdAccountMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserAgentMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserDepartMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserRoleMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/SysVersionMapper.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/DpUserMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementSendMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCategoryMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCheckRuleMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDataSourceMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartPermissionMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRolePermissionMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleUserMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictItemMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysFillRuleMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysGatewayRouteMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysLogMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionDataRuleMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPositionMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysRoleIndexMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysTenantMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysThirdAccountMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserAgentMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserDepartMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysVersionMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/UploadVideoFileManageMapper.xml create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/AnnouncementSendModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/DepartIdModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/DuplicateCheckVo.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/SysDepartTreeModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/SysDictTree.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/SysLoginModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/SysPermissionTree.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/SysUserSysDepartModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/ThirdLoginModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/TreeModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/model/TreeSelectModel.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/rule/CategoryCodeRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/rule/OrderNumberRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/rule/OrgCodeRule.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/security/DictQueryBlackListHandler.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/IDpUserService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementSendService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysCategoryService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysCheckRuleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataLogService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataSourceService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartPermissionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRolePermissionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleUserService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictItemService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysFillRuleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysGatewayRouteService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysLogService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionDataRuleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysPositionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleIndexService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysRolePermissionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysTenantService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysThirdAccountService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserAgentService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserDepartService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserRoleService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/ISysVersionService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/IThirdAppService.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/DpUserServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/ImportFileServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementSendServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysBaseApiImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCategoryServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCheckRuleServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataLogServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataSourceServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartPermissionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRolePermissionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleUserServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictItemServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysFillRuleServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysGatewayRouteServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysLogServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionDataRuleImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPositionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleIndexServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRolePermissionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysTenantServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserAgentServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserDepartServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserRoleServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysVersionServiceImpl.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/util/FindsDepartsChildrenUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/util/PermissionDataUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/util/RandImageUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/util/SecurityUtil.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/util/XSSUtils.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysDepartUsersVO.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysDictPage.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserDepVo.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserOnlineVO.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserRoleVO.java create mode 100644 digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserVO.java create mode 100644 pom.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9770263 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/digital-common/digital-base/target/ +/digital-common/digital-util/target/ +/digital-common/digital-config/target/ +digital-common/digital-bean/target/ +digital-application/target/ +digital-system/target/ +.idea diff --git a/README.en.md b/README.en.md new file mode 100644 index 0000000..be8c42b --- /dev/null +++ b/README.en.md @@ -0,0 +1,36 @@ +# digital-cloth-backend-service + +#### Description +{**When you're done, you can delete the content in this README and update the file with details for others getting started with your repository**} + +#### Software Architecture +Software architecture description + +#### Installation + +1. xxxx +2. xxxx +3. xxxx + +#### Instructions + +1. xxxx +2. xxxx +3. xxxx + +#### Contribution + +1. Fork the repository +2. Create Feat_xxx branch +3. Commit your code +4. Create Pull Request + + +#### Gitee Feature + +1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md +2. Gitee blog [blog.gitee.com](https://blog.gitee.com) +3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) +4. The most valuable open source project [GVP](https://gitee.com/gvp) +5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) +6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md new file mode 100644 index 0000000..878fef3 --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +# digital-cloth-backend-service + +#### 介绍 +{**以下是 Gitee 平台说明,您可以替换此简介** +Gitee 是 OSCHINA 推出的基于 Git 的代码托管平台(同时支持 SVN)。专为开发者提供稳定、高效、安全的云端软件开发协作平台 +无论是个人、团队、或是企业,都能够用 Gitee 实现代码托管、项目管理、协作开发。企业项目请看 [https://gitee.com/enterprises](https://gitee.com/enterprises)} + +#### 软件架构 +软件架构说明 + + +#### 安装教程 + +1. xxxx +2. xxxx +3. xxxx + +#### 使用说明 + +1. xxxx +2. xxxx +3. xxxx + +#### 参与贡献 + +1. Fork 本仓库 +2. 新建 Feat_xxx 分支 +3. 提交代码 +4. 新建 Pull Request + + +#### 特技 + +1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md +2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) +3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 +4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 +5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) +6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/digital-application/pom.xml b/digital-application/pom.xml new file mode 100644 index 0000000..e8f24e2 --- /dev/null +++ b/digital-application/pom.xml @@ -0,0 +1,188 @@ + + + + jeecg-boot-parent + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-application + + + 8 + 8 + + + + + + + org + jaudiotagger + 2.0.1 + + + + + com.googlecode.mp4parser + isoparser + 1.1.22 + + + + + com.tencentcloudapi + tencentcloud-sdk-java-asr + 3.1.957 + + + org.apache.httpcomponents + httpclient + 4.5.6 + + + org.apache.httpcomponents + httpmime + 4.5.6 + + + + com.squareup.okhttp3 + okhttp + 4.8.0 + + + + net.logstash.logback + logstash-logback-encoder + 6.0 + + + + com.mashape.unirest + unirest-java + 1.4.9 + + + + + org.springframework.boot + spring-boot-starter-validation + + + + org.jeecgframework.boot + digital-util + 3.2.0 + compile + + + + org.jeecgframework.boot + digital-base + 3.2.0 + compile + + + + com.volcengine + volcengine-java-sdk-vpc + 0.1.142 + + + com.volcengine + volcengine-java-sdk-ecs + 0.1.142 + + + + com.volcengine + ve-tos-java-sdk + 2.8.7 + + + + + org.jeecgframework.boot + digital-bean + 3.2.0 + compile + + + + org.jeecgframework.boot + digital-config + 3.2.0 + compile + + + + com.tencentcloudapi + tencentcloud-sdk-java-live + 3.1.956 + + + + org.jeecgframework.boot + digital-system + 3.2.0 + compile + + + + + + mysql + mysql-connector-java + ${mysql-connector-java.version} + runtime + + + + org.springframework.boot + spring-boot-starter-web + true + + + io.swagger + swagger-annotations + 1.5.22 + compile + + + org.mybatis + mybatis-spring + 2.0.6 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + false + + + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + + true + digital.application.DigitalApplication + + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/DigitalApplication.java b/digital-application/src/main/java/digital/application/DigitalApplication.java new file mode 100644 index 0000000..8e9a005 --- /dev/null +++ b/digital-application/src/main/java/digital/application/DigitalApplication.java @@ -0,0 +1,53 @@ +package digital.application; + +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration; +import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.core.env.Environment; +import org.springframework.scheduling.annotation.EnableAsync; +import org.springframework.scheduling.annotation.EnableScheduling; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * 单体启动类(采用此类启动为单体模式) + * 特别提醒: + * 1.需要集成mongodb请删除 exclude={MongoAutoConfiguration.class} + * 2.切换微服务 勾选profile的SpringCloud,这个类就无法启动,启动会报错 + */ +@Slf4j +@EnableScheduling +@SpringBootApplication(exclude = {RedisAutoConfiguration.class}) +@ComponentScan(basePackages = {"digital"}) +@EnableAsync +@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class}) +public class DigitalApplication extends SpringBootServletInitializer { + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { + return application.sources(DigitalApplication.class); + } + public static void main(String[] args) throws UnknownHostException { + ConfigurableApplicationContext application = SpringApplication.run(DigitalApplication.class, args); + Environment env = application.getEnvironment(); + String ip = InetAddress.getLocalHost().getHostAddress(); + String port = env.getProperty("server.port"); + String path = oConvertUtils.getString(env.getProperty("server.servlet.context-path")); + log.info("\n----------------------------------------------------------\n\t" + + "Application digital is running! Access URLs:\n\t" + + "Local: \t\thttp://localhost:" + port + path + "/\n\t" + + "External: \thttp://" + ip + ":" + port + path + "/\n\t" + + "Swagger文档: \thttp://" + ip + ":" + port + path + "/doc.html\n" + + "----------------------------------------------------------"); + + } + +} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskExecutor.java b/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskExecutor.java new file mode 100644 index 0000000..5cba1d1 --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskExecutor.java @@ -0,0 +1,38 @@ +package digital.application.ScheduleTask; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +@Slf4j +public class ClothTaskExecutor { + + @Autowired + private ClothTaskService clothTaskService; + + @PostConstruct + public void init() { + // 使用自定义的ThreadFactory来设置线程名字 + // 使用线程池执行任务处理线程 + ExecutorService executorService = Executors.newSingleThreadExecutor(); + // 任务处理线程1 + executorService.execute(() -> { + try { + log.info("启动==换装==处理线程..." + Thread.currentThread().getName()); + if (clothTaskService != null) { + clothTaskService.startClothProcessingTasks(); + } else { + log.error("taskService 为 null,无法启动任务处理"); + } + } catch (Exception e) { + log.error("任务==换装==处理线程启动失败", e); + } + }); + // 关闭线程池(应用关闭时) + // executorService.shutdown(); + } +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskService.java b/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskService.java new file mode 100644 index 0000000..a22d700 --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/ClothTaskService.java @@ -0,0 +1,168 @@ +package digital.application.ScheduleTask; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.application.entity.SysHistory; +import digital.application.entity.SysTaskQueue; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.mapper.SysHistoryMapper; +import digital.application.service.SysTaskQueueService; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.constant.ZitaCommonConstant; +import digital.bean.task.MwTrainTask; +import digital.config.oss.OssConfiguration; +import digital.util.oss.OssBootUtil; +import digital.util.util.RestUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.UUID; +import java.util.concurrent.*; + +@Component +@Slf4j +public class ClothTaskService { + + @Autowired + OssConfiguration ossConfiguration; + @Autowired + private SysTaskQueueService sysTaskQueueService; + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Autowired + private SysHistoryMapper sysHistoryMapper; + + private ScheduledExecutorService executorService; + private BlockingQueue clothTaskQueue = new LinkedBlockingQueue<>(); + + public ClothTaskService() { + this.executorService = Executors.newSingleThreadScheduledExecutor(); + } + + @Scheduled(fixedRate = 3000) // 每隔3秒执行一次 + @Transactional + public synchronized void pollClothTaskTable() { + String taskId = UUID.randomUUID().toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_SINGLE) + .and(wrapper -> wrapper.isNull(SysTaskQueue::getTryOnAlgo) + .or().eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TRY_ON_TYPE_ALGO_CLOTH)) + .last("LIMIT 1"); // 添加这个条件来限制查询结果为1条 +// log.info(Thread.currentThread().getName() + "放入【换装】队列前,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + SysTaskQueue sysTaskQueue = sysTaskQueueService.getOne(queryWrapper); + if (null == sysTaskQueue) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_BATCH) + .and(wrapper -> wrapper.isNull(SysTaskQueue::getTryOnAlgo) + .or().eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TRY_ON_TYPE_ALGO_CLOTH)) // 假设 "cloth" 是你要比较的值 + .last("LIMIT 1"); // 限制只返回一条记录 + sysTaskQueue = sysTaskQueueService.getOne(qw); + } + if (sysTaskQueue != null && clothTaskQueue.size() < 1) { + clothTaskQueue.offer(sysTaskQueue); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysTaskQueueService.updateById(sysTaskQueue); + } +// log.info(Thread.currentThread().getName() + " 放入【换装】队列后,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + } + + public void startClothProcessingTasks() { + executorService.scheduleAtFixedRate(() -> { +// log.info("当前【换装】队列大小=" + clothTaskQueue.size()); + SysTaskQueue clothTask = clothTaskQueue.poll(); +// log.info("当前【换装】队列大小=" + clothTaskQueue.size()); + if (clothTask != null) { + // 执行任务 + processTask(clothTask); + } + }, 0, 3, TimeUnit.SECONDS); + } + + + private synchronized void processTask(SysTaskQueue sysTaskQueue) { + String taskId = sysTaskQueue.getTaskId(); + long startTime = System.currentTimeMillis(); + log.info(Thread.currentThread().getName() + " 开始【换装】=========================================:taskId==" + taskId + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + String jsonInfo = sysTaskQueue.getJsonInfo(); + JSONObject clothParam = JSON.parseObject(jsonInfo); + MwTrainTask trainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, taskId)); + //防止数据删除空指针 + SysHistory sysHistory = sysHistoryMapper.selectHistoryOne(taskId); + try { + String url; + if (ZitaCommonConstant.sex_male.equals(sysTaskQueue.getSex())) { + url = Face3dSeverHTTPConstant.SWAP_CLOTH_MALE; + } else { + url = Face3dSeverHTTPConstant.SWAP_CLOTH; + } + ResponseEntity clothResult = RestUtil.zitaRequest(url, + HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = clothResult.getBody().get("status").toString(); + log.info(taskId + " 返回结果信息成功 ==" + taskId + " clothResult=" + clothResult.getBody()); + if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult(String.format("digital cloth 【换装】任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + trainTaskMapper.updateById(trainTask); + log.info(String.format("digital cloth 【换装】任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + // 尝试将返回结果转为JSON + JSONObject resultBody = clothResult.getBody(); + String imagePath = (String) resultBody.get("data"); + File file = new File(imagePath); + String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); + String fileUrl = OssBootUtil.uploadOssVideo(file, CommonConstant.PUTON_SWAP, newFileName); + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + trainTask.setResultImages(savePath); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + trainTask.setResult(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + long endTime = System.currentTimeMillis(); + long duration = (endTime - startTime) / 1000; // 除以1000,将毫秒转换为秒 + trainTask.setCostTime((int) duration); + trainTaskMapper.updateById(trainTask); + //替换换装后的照片 + sysHistory.setFileUrl(savePath); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysTaskQueueService.updateById(sysTaskQueue); + } catch (Exception ex) { + String message = ex.getMessage(); + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult("digital cloth 【换装】失败!" + String.format("%s {taskId: %s}", message, taskId)); + trainTaskMapper.updateById(trainTask); + log.error("digital cloth 【换装】任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + log.info(Thread.currentThread().getName() + "结束【换装】=========================================:" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + } + +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskExecutor.java b/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskExecutor.java new file mode 100644 index 0000000..a07dd62 --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskExecutor.java @@ -0,0 +1,39 @@ +package digital.application.ScheduleTask; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +@Slf4j +public class FigureTaskExecutor { + + @Autowired + private FigureTaskService figureTaskService; + + @PostConstruct + public void init() { + // 使用自定义的ThreadFactory来设置线程名字 + // 使用线程池执行任务处理线程 + ExecutorService executorService = Executors.newSingleThreadExecutor(); + // 任务处理线程1 + executorService.execute(() -> { + try { + log.info("启动==换身材==处理线程..." + Thread.currentThread().getName()); + if (figureTaskService != null) { + figureTaskService.startClothProcessingTasks(); + } else { + log.error("换身材 taskService 为 null,无法启动任务处理"); + } + } catch (Exception e) { + log.error("任务==换身材==处理线程启动失败", e); + } + }); + // 关闭线程池(应用关闭时) + // executorService.shutdown(); + } +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskService.java b/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskService.java new file mode 100644 index 0000000..9f43eeb --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/FigureTaskService.java @@ -0,0 +1,160 @@ +package digital.application.ScheduleTask; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.application.entity.SysHistory; +import digital.application.entity.SysTaskQueue; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.mapper.SysHistoryMapper; +import digital.application.service.SysTaskQueueService; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.constant.ZitaCommonConstant; +import digital.bean.task.MwTrainTask; +import digital.config.oss.OssConfiguration; +import digital.util.oss.OssBootUtil; +import digital.util.util.RestUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.UUID; +import java.util.concurrent.*; + +@Component +@Slf4j +public class FigureTaskService { + + @Autowired + OssConfiguration ossConfiguration; + @Autowired + private SysTaskQueueService sysTaskQueueService; + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Autowired + private SysHistoryMapper sysHistoryMapper; + + private ScheduledExecutorService executorService; + private BlockingQueue figureTaskQueue = new LinkedBlockingQueue<>(); + + public FigureTaskService() { + this.executorService = Executors.newSingleThreadScheduledExecutor(); + } + + @Scheduled(fixedRate = 3000) // 每隔3秒执行一次 + @Transactional + public synchronized void pollClothTaskTable() { + String taskId = UUID.randomUUID().toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_SINGLE) + .eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TYPE_FIGURE) + .last("LIMIT 1"); // 添加这个条件来限制查询结果为1条 +// log.info(Thread.currentThread().getName() + "放入【换身材】队列前,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + SysTaskQueue sysTaskQueue = sysTaskQueueService.getOne(queryWrapper); + if (null == sysTaskQueue) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_BATCH) + .eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TYPE_FIGURE) + .last("LIMIT 1"); // 限制只返回一条记录 + sysTaskQueue = sysTaskQueueService.getOne(qw); + } + if (sysTaskQueue != null && figureTaskQueue.size() < 1) { + figureTaskQueue.offer(sysTaskQueue); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysTaskQueueService.updateById(sysTaskQueue); + } +// log.info(Thread.currentThread().getName() + " 放入【换身材】队列后,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + } + + public void startClothProcessingTasks() { + executorService.scheduleAtFixedRate(() -> { +// log.info("当前【换身材】队列大小=" + clothTaskQueue.size()); + SysTaskQueue figureTask = figureTaskQueue.poll(); +// log.info("当前【换身材】队列大小=" + clothTaskQueue.size()); + if (figureTask != null) { + // 执行任务 + processTask(figureTask); + } + }, 0, 3, TimeUnit.SECONDS); + } + + + private synchronized void processTask(SysTaskQueue sysTaskQueue) { + String taskId = sysTaskQueue.getTaskId(); + long startTime = System.currentTimeMillis(); + log.info(Thread.currentThread().getName() + " 开始【换身材】=========================================:taskId==" + taskId + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + String jsonInfo = sysTaskQueue.getJsonInfo(); + JSONObject clothParam = JSON.parseObject(jsonInfo); + MwTrainTask trainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, taskId)); + //防止数据删除空指针 + SysHistory sysHistory = sysHistoryMapper.selectHistoryOne(taskId); + try { + ResponseEntity clothResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.FIGURE_UPLOAD, + HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = clothResult.getBody().get("status").toString(); + log.info(taskId + " 返回结果信息成功 ==" + taskId + " clothResult=" + clothResult.getBody()); + if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult(String.format("digital figure 【换身材】任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + trainTaskMapper.updateById(trainTask); + log.info(String.format("digital figure 【换身材】任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + // 尝试将返回结果转为JSON + JSONObject resultBody = clothResult.getBody(); + String imagePath = (String) resultBody.get("res_img_path"); + File file = new File(imagePath); + String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); + String fileUrl = OssBootUtil.uploadOssVideo(file, CommonConstant.PUTON_SWAP, newFileName); + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + trainTask.setResultImages(savePath); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + trainTask.setResult(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + long endTime = System.currentTimeMillis(); + long duration = (endTime - startTime) / 1000; // 除以1000,将毫秒转换为秒 + trainTask.setCostTime((int) duration); + trainTaskMapper.updateById(trainTask); + //替换换身材后的照片 + sysHistory.setFileUrl(savePath); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysTaskQueueService.updateById(sysTaskQueue); + } catch (Exception ex) { + String message = ex.getMessage(); + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult("digital figure 【换身材】失败!" + String.format("%s {taskId: %s}", message, taskId)); + trainTaskMapper.updateById(trainTask); + log.error("digital figure 【换身材】任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + log.info(Thread.currentThread().getName() + "结束【换身材】=========================================:" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + } + +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskExecutor.java b/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskExecutor.java new file mode 100644 index 0000000..9b194f3 --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskExecutor.java @@ -0,0 +1,38 @@ +package digital.application.ScheduleTask; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +@Slf4j +public class HairTaskExecutor { + + @Autowired + private HairTaskService HairTaskService; + + @PostConstruct + public void init() { + // 使用线程池执行任务处理线程 + ExecutorService executorService = Executors.newSingleThreadExecutor(); + // 任务处理线程2 + executorService.execute(() -> { + try { + log.info("启动==换发型==处理线程..." + Thread.currentThread().getName()); + if (HairTaskService != null) { + HairTaskService.startHairProcessingTasks(); + } else { + log.error("taskService 为 null,无法启动任务处理"); + } + } catch (Exception e) { + log.error("任务==换发型==处理线程启动失败", e); + } + }); + // 关闭线程池(应用关闭时) + // executorService.shutdown(); + } +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskService.java b/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskService.java new file mode 100644 index 0000000..a5c7d6e --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/HairTaskService.java @@ -0,0 +1,224 @@ +package digital.application.ScheduleTask; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.application.entity.SysHistory; +import digital.application.entity.SysTaskQueue; +import digital.application.entity.SysWhiteUser; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.mapper.SysHistoryMapper; +import digital.application.mapper.SysWhiteUserMapper; +import digital.application.service.SysTaskQueueService; +import digital.application.utils.CloudStorageService; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.constant.ZitaCommonConstant; +import digital.bean.task.DpUser; +import digital.bean.task.MwTrainTask; +import digital.config.oss.OssConfiguration; +import digital.system.jeecg.system.service.IDpUserService; +import digital.util.util.RestUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.io.InputStream; +import java.net.URL; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.*; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class HairTaskService { + + @Autowired + OssConfiguration ossConfiguration; + @Autowired + private SysTaskQueueService sysTaskQueueService; + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Autowired + private SysHistoryMapper sysHistoryMapper; + @Autowired + private SysWhiteUserMapper smsWhiteUserMapper; + @Autowired + private IDpUserService dpUserService; + + private ScheduledExecutorService executorService; + private BlockingQueue hairTaskQueue; + + public HairTaskService() { + this.executorService = Executors.newSingleThreadScheduledExecutor(); + this.hairTaskQueue = new LinkedBlockingQueue<>(); + } + + @Scheduled(fixedRate = 3000) // 每隔3秒执行一次 + @Transactional + public void pollHairTaskTable() { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + queryWrapper.lambda().eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_SINGLE); + queryWrapper.lambda().eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TRY_ON_TYPE_ALGO_HAIR); + queryWrapper.lambda().orderByAsc(SysTaskQueue::getId); + queryWrapper.lambda().last("LIMIT 1"); +// log.info(Thread.currentThread().getName() + "放入【换发型】队列前,hairTaskQueue = " + hairTaskQueue.size()); + SysTaskQueue sysTaskQueue = sysTaskQueueService.getOne(queryWrapper); + if (null == sysTaskQueue) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda().eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + qw.lambda().eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_BATCH); + qw.lambda().eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TRY_ON_TYPE_ALGO_HAIR); + qw.lambda().orderByAsc(SysTaskQueue::getId); + qw.lambda().last("LIMIT 1"); + sysTaskQueue = sysTaskQueueService.getOne(qw); + } + if (sysTaskQueue != null && hairTaskQueue.size() < 1) { + hairTaskQueue.offer(sysTaskQueue); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysTaskQueueService.updateById(sysTaskQueue); + } +// log.info(Thread.currentThread().getName() + "放入【换发型】队列后,hairTaskQueue = " + hairTaskQueue.size()); + } + + public synchronized void startHairProcessingTasks() { + executorService.scheduleAtFixedRate(() -> { +// log.info("当前【换发型】队列大小=" + hairTaskQueue.size()); + SysTaskQueue hairTask = hairTaskQueue.poll(); +// log.info("当前【换发型】队列大小=" + hairTaskQueue.size()); + if (hairTask != null) { + // 执行任务 + processHairTask(hairTask); + } + }, 0, 1, TimeUnit.SECONDS); + } + + @Transactional + synchronized void processHairTask(SysTaskQueue sysTaskQueue) { + String taskId = sysTaskQueue.getTaskId(); + long startTime = System.currentTimeMillis(); + log.info("开始【换发型】 =========================================:" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + String jsonInfo = sysTaskQueue.getJsonInfo(); + JSONObject hairParam = JSON.parseObject(jsonInfo); + MwTrainTask trainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, taskId)); + //防止数据删除空指针 + SysHistory sysHistory = sysHistoryMapper.selectHistoryOne(taskId); + try { + DpUser dpUser = dpUserService.getByUserId(sysTaskQueue.getUserId()); + List sysWhiteUsers = smsWhiteUserMapper.selectList(new QueryWrapper().lambda().eq(SysWhiteUser::getDelFlag, CommonConstant.DEL_FLAG_0)); + String url = Face3dSeverHTTPConstant.SWAP_HAIR_v1; + if (null != dpUser && sysWhiteUsers != null) { + List accounts = sysWhiteUsers.stream() + .map(SysWhiteUser::getAccount) // 将Person对象映射到它们的name字段 + .collect(Collectors.toList()); // 收集映射后的结果到List中 + if (accounts.contains(dpUser.getAccount())) { + url = Face3dSeverHTTPConstant.SWAP_HAIR_v2; + } + } + ResponseEntity hairResult = RestUtil.zitaRequest(url, + HttpMethod.POST, null, hairParam, JSONObject.class); + String clothState = hairResult.getStatusCodeValue() + ""; + log.info(taskId + " 返回结果信息成功 ==" + taskId + " hairResult=" + hairResult.getBody()); + if (clothState != null && !ZitaCommonConstant.STATUS_NORMAL.equals(clothState) + || hairResult != null && hairResult.getBody() != null + && !("0").equals(hairResult.getBody().getString("state"))) { + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult(String.format("digital 【换发型】 任务失败!{taskId: %s, resp: %s}", taskId, hairResult.getBody().toJSONString())); + trainTaskMapper.updateById(trainTask); + log.info(String.format("digital 【换发型】 任务失败!{taskId: %s, resp: %s}", taskId, hairResult.getBody().toJSONString())); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + // 尝试将返回结果转为JSON + JSONObject resultBody = hairResult.getBody(); + String imageP = (String) resultBody.get("data"); + + // 判断手机号码 + if (Objects.equals(dpUser.getAccount(), "13763009010")) { + // 获取图片流 + String imgName = getFileNameFromURL(imageP); + InputStream imageStream = downloadImageStream(imageP); + // 上传到客户oss + String resReUrl = CloudStorageService.saveFileToBucket(imgName, imageStream); + imageP = resReUrl; + } + + trainTask.setResultImages(imageP); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + trainTask.setResult(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + long endTime = System.currentTimeMillis(); + long duration = (endTime - startTime) / 1000; // 除以1000,将毫秒转换为秒 + trainTask.setCostTime((int) duration); + trainTaskMapper.updateById(trainTask); + //替换换装后的照片 + sysHistory.setFileUrl(imageP); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysTaskQueueService.updateById(sysTaskQueue); + } catch (Exception ex) { + String message = ex.getMessage(); + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult("digital 【换发型】 任务失败!" + String.format("digital 【换发型】 任务失败!详情: {taskId: {}, message: {}}", message, taskId)); + trainTaskMapper.updateById(trainTask); + log.error("digital 【换发型】 任务失败!详情: {taskId: {}, message: {}}", taskId, message); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + log.info("结束【换发型】========================================:" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + } + + + public static InputStream downloadImageStream(String imageUrl) { + // 创建一个 URL 对象 + try { + URL url = new URL(imageUrl); + + // 打开一个到 URL 指向的资源的连接 + // 这里我们可以直接使用 URL.openStream() 方法来获取 InputStream + // 也可以使用 HttpURLConnection 来获取更多的连接控制(比如设置请求头、处理重定向等) + InputStream inputStream = url.openStream(); + + // 返回 InputStream,注意这里没有关闭它,因为调用者可能还需要使用它 + // 调用者应该在不再需要时关闭 InputStream 以释放资源 + return inputStream; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + + public static String getFileNameFromURL(String urlString) { + try { + URL url = new URL(urlString); + // 使用URI和Paths来获取文件名 + String fileName = url.getFile(); + fileName = fileName.substring(fileName.lastIndexOf("/") + 1); // 获取文件名 + return fileName; + } catch (Exception e) { + e.printStackTrace(); + return null; // 或者抛出一个自定义的异常 + } + } + +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskExecutor.java b/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskExecutor.java new file mode 100644 index 0000000..0e0977c --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskExecutor.java @@ -0,0 +1,39 @@ +package digital.application.ScheduleTask; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +@Component +@Slf4j +public class UnderwearTaskExecutor { + + @Autowired + private UnderwearTaskService underwearTaskService; + + @PostConstruct + public void init() { + // 使用自定义的ThreadFactory来设置线程名字 + // 使用线程池执行任务处理线程 + ExecutorService executorService = Executors.newSingleThreadExecutor(); + // 任务处理线程1 + executorService.execute(() -> { + try { + log.info("启动==换内衣==处理线程..." + Thread.currentThread().getName()); + if (underwearTaskService != null) { + underwearTaskService.startClothProcessingTasks(); + } else { + log.error("换内衣 taskService 为 null,无法启动任务处理"); + } + } catch (Exception e) { + log.error("任务==换内衣==处理线程启动失败", e); + } + }); + // 关闭线程池(应用关闭时) + // executorService.shutdown(); + } +} diff --git a/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskService.java b/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskService.java new file mode 100644 index 0000000..bb3d552 --- /dev/null +++ b/digital-application/src/main/java/digital/application/ScheduleTask/UnderwearTaskService.java @@ -0,0 +1,160 @@ +package digital.application.ScheduleTask; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.application.entity.SysHistory; +import digital.application.entity.SysTaskQueue; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.mapper.SysHistoryMapper; +import digital.application.service.SysTaskQueueService; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.constant.ZitaCommonConstant; +import digital.bean.task.MwTrainTask; +import digital.config.oss.OssConfiguration; +import digital.util.oss.OssBootUtil; +import digital.util.util.RestUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.io.File; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.UUID; +import java.util.concurrent.*; + +@Component +@Slf4j +public class UnderwearTaskService { + + @Autowired + OssConfiguration ossConfiguration; + @Autowired + private SysTaskQueueService sysTaskQueueService; + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Autowired + private SysHistoryMapper sysHistoryMapper; + + private ScheduledExecutorService executorService; + private BlockingQueue underwearTaskQueue = new LinkedBlockingQueue<>(); + + public UnderwearTaskService() { + this.executorService = Executors.newSingleThreadScheduledExecutor(); + } + + @Scheduled(fixedRate = 3000) // 每隔3秒执行一次 + @Transactional + public synchronized void pollClothTaskTable() { + String taskId = UUID.randomUUID().toString(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_SINGLE) + .eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TYPE_UNDERWEAR) + .last("LIMIT 1"); // 添加这个条件来限制查询结果为1条 +// log.info(Thread.currentThread().getName() + "放入【换内衣】队列前,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + SysTaskQueue sysTaskQueue = sysTaskQueueService.getOne(queryWrapper); + if (null == sysTaskQueue) { + QueryWrapper qw = new QueryWrapper<>(); + qw.lambda() + .eq(SysTaskQueue::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT) + .orderByAsc(SysTaskQueue::getId) + .eq(SysTaskQueue::getTryOnType, CommonConstant.TRY_ON_TYPE_BATCH) + .eq(SysTaskQueue::getTryOnAlgo, CommonConstant.TYPE_UNDERWEAR) + .last("LIMIT 1"); // 限制只返回一条记录 + sysTaskQueue = sysTaskQueueService.getOne(qw); + } + if (sysTaskQueue != null && underwearTaskQueue.size() < 1) { + underwearTaskQueue.offer(sysTaskQueue); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysTaskQueueService.updateById(sysTaskQueue); + } +// log.info(Thread.currentThread().getName() + " 放入【换内衣】队列后,clothTaskQueue = " + clothTaskQueue.size() + " taskId == " + taskId); + } + + public void startClothProcessingTasks() { + executorService.scheduleAtFixedRate(() -> { +// log.info("当前【换内衣】队列大小=" + clothTaskQueue.size()); + SysTaskQueue figureTask = underwearTaskQueue.poll(); +// log.info("当前【换内衣】队列大小=" + clothTaskQueue.size()); + if (figureTask != null) { + // 执行任务 + processTask(figureTask); + } + }, 0, 3, TimeUnit.SECONDS); + } + + + private synchronized void processTask(SysTaskQueue sysTaskQueue) { + String taskId = sysTaskQueue.getTaskId(); + long startTime = System.currentTimeMillis(); + log.info(Thread.currentThread().getName() + " 开始【换内衣】=========================================:taskId==" + taskId + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + String jsonInfo = sysTaskQueue.getJsonInfo(); + JSONObject clothParam = JSON.parseObject(jsonInfo); + MwTrainTask trainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, taskId)); + //防止数据删除空指针 + SysHistory sysHistory = sysHistoryMapper.selectHistoryOne(taskId); + try { + ResponseEntity underwearResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.SWAP_UNDERWEAR, + HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = underwearResult.getBody().get("status").toString(); + log.info(taskId + " 返回结果信息成功 ==" + taskId + " underwearResult=" + underwearResult.getBody()); + if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult(String.format("digital figure 【换内衣】任务失败!{taskId: %s, resp: %s}", taskId, underwearResult.getBody().toJSONString())); + trainTaskMapper.updateById(trainTask); + log.info(String.format("digital figure 【换内衣】任务失败!{taskId: %s, resp: %s}", taskId, underwearResult.getBody().toJSONString())); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + // 尝试将返回结果转为JSON + JSONObject resultBody = underwearResult.getBody(); + String imagePath = (String) resultBody.get("data"); + File file = new File(imagePath); + String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); + String fileUrl = OssBootUtil.uploadOssVideo(file, CommonConstant.PUTON_SWAP, newFileName); + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + trainTask.setResultImages(savePath); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + trainTask.setResult(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + long endTime = System.currentTimeMillis(); + long duration = (endTime - startTime) / 1000; // 除以1000,将毫秒转换为秒 + trainTask.setCostTime((int) duration); + trainTaskMapper.updateById(trainTask); + //替换换内衣后的照片 + sysHistory.setFileUrl(savePath); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysTaskQueueService.updateById(sysTaskQueue); + } catch (Exception ex) { + String message = ex.getMessage(); + trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); + trainTask.setResult(Face3dSeverHTTPConstant.result_fail); + trainTask.setRequestResult("digital figure 【换内衣】失败!" + String.format("%s {taskId: %s}", message, taskId)); + trainTaskMapper.updateById(trainTask); + log.error("digital figure 【换内衣】任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); + sysHistoryMapper.updateById(sysHistory); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.result_fail); + sysTaskQueueService.updateById(sysTaskQueue); + return; + } + log.info(Thread.currentThread().getName() + "结束【换内衣】=========================================:" + LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); + } + +} diff --git a/digital-application/src/main/java/digital/application/controller/DigitalClothController.java b/digital-application/src/main/java/digital/application/controller/DigitalClothController.java new file mode 100644 index 0000000..03f6ebc --- /dev/null +++ b/digital-application/src/main/java/digital/application/controller/DigitalClothController.java @@ -0,0 +1,399 @@ +package digital.application.controller; + +import cn.hutool.core.util.DesensitizedUtil; +import cn.hutool.core.util.RandomUtil; +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.exceptions.ClientException; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.application.dto.*; +import digital.application.entity.SysFile; +import digital.application.service.IMwTrainTaskService; +import digital.application.service.ISysContactService; +import digital.application.service.ISysFileService; +import digital.application.service.SysRoomService; +import digital.application.vo.LoginUserInfoVO; +import digital.base.annotation.AutoLog; +import digital.base.constant.CommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.bean.task.DpUser; +import digital.system.jeecg.group.base.service.BaseCommonService; +import digital.system.jeecg.system.service.IDpUserService; +import digital.util.util.*; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +@Api(tags = "换装平台API") +@RestController +@RequestMapping("/api/cloth") +@Slf4j +public class DigitalClothController { + + @Autowired + private IDpUserService dpUserService; + @Autowired + private ISysFileService sysFileService; + @Autowired + private JeecgRedisUtil redisUtil; + @Resource + private BaseCommonService baseCommonService; + @Autowired + private IMwTrainTaskService mwTrainTaskService; + @Autowired + private ISysContactService sysContactService; + @Autowired + private SysRoomService sysRoomService; + + @AutoLog(value = "添加专题试衣间") + @ApiOperation(value = "添加专题试衣间", notes = "添加专题试衣间") + @PostMapping(value = "/addRoom") + public Result addRoom(@RequestBody @Validated AddRoomDTO addRoomDTO) { + return sysRoomService.addRoom(addRoomDTO); + } + + @AutoLog(value = "删除专题试衣间") + @ApiOperation(value = "删除专题试衣间", notes = "删除专题试衣间") + @PostMapping(value = "/delRoom") + public Result delRoom(@RequestBody @Validated DelRoomDTO delRoomDTO) { + return sysRoomService.delRoom(delRoomDTO); + } + + @AutoLog(value = "修改专题试衣间") + @ApiOperation(value = "修改专题试衣间", notes = "修改专题试衣间") + @PostMapping(value = "/updateRoom") + public Result updateRoom(@RequestBody @Validated UpdateRoomDTO updateRoomDTO) { + return sysRoomService.updateRoom(updateRoomDTO); + } + + @AutoLog(value = "查询本人专题试衣间") + @ApiOperation(value = "查询本人专题试衣间", notes = "查询本人专题试衣间") + @PostMapping(value = "/getRoomList") + public Result getRoomList(@RequestBody @Validated GetRoomListDTO getRoomListDTO) { + return sysRoomService.getRoomList(getRoomListDTO); + } + + @AutoLog(value = "专题试衣间-添加衣服") + @ApiOperation(value = "专题试衣间-添加衣服", notes = "专题试衣间-添加衣服") + @PostMapping(value = "/addRoomCloth") + public Result addRoomCloth(@RequestBody @Validated AddRoomClothDTO addRoomClothDTO) { + return sysRoomService.addRoomCloth(addRoomClothDTO); + } + + @AutoLog(value = "专题试衣间-删除衣服") + @ApiOperation(value = "专题试衣间-删除衣服", notes = "专题试衣间-删除衣服") + @PostMapping(value = "/delRoomCloth") + public Result delRoomCloth(@RequestBody @Validated AddRoomClothDTO addRoomClothDTO) { + return sysRoomService.delRoomCloth(addRoomClothDTO); + } + + @AutoLog(value = "专题试衣间-查询对应试衣间列表") + @ApiOperation(value = "专题试衣间-查询对应试衣间列表", notes = "专题试衣间-查询对应试衣间列表") + @PostMapping(value = "/getRoomClothList") + public Result getRoomClothList(@RequestBody @Validated GetRoomClothListDTO getRoomClothListDTO) { + return sysRoomService.getRoomClothList(getRoomClothListDTO); + } + + @AutoLog(value = "购买链接") + @ApiOperation(value = "购买链接", notes = "购买链接") + @PostMapping(value = "/buyLink") + public Result buyLink(@RequestBody @Validated BuyLinksDTO buyLinksDTO) { + return sysFileService.buyLink(buyLinksDTO); + } + + @AutoLog(value = "批量删除历史数据") + @ApiOperation(value = "批量删除历史数据", notes = "批量删除历史数据") + @PostMapping(value = "/batchDelHistory") + public Result batchDelHistory(@RequestBody @Validated BatchDelHistoryDTO batchDelHistoryDTO) { + return sysFileService.batchDelHistory(batchDelHistoryDTO); + } + + @AutoLog(value = "取消试穿") + @ApiOperation(value = "取消试穿", notes = "取消试穿") + @PostMapping(value = "/unTryOn") + public Result unTryOn(@RequestBody @Validated UnTryOnDTO unTryOnDTO) { + return sysFileService.unTryOn(unTryOnDTO); + } + + + @AutoLog(value = "上传用户头像") + @ApiOperation(value = "上传用户头像", notes = "上传用户头像") + @PostMapping(value = "/uploadAvatar") + public Result uploadAvatar(@RequestParam("file") MultipartFile file) { + return sysFileService.uploadAvatar(file); + } + + @AutoLog(value = "获取登录用户信息") + @ApiOperation(value = "获取登录用户信息", notes = "获取登录用户信息") + @PostMapping(value = "/getLoginUserInfo") + public Result getLoginUserInfo() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info("开始 获取登录用户信息 loginUser =" + loginUser); + DpUser dpUser = dpUserService.getByUserId(loginUser.getId()); + log.info("开始 获取登录用户信息 dpUser =" + dpUser); + LoginUserInfoVO loginUserInfoVO = new LoginUserInfoVO(); + BeanUtils.copyProperties(dpUser, loginUserInfoVO); + loginUserInfoVO.setUsername(DesensitizedUtil.mobilePhone(dpUser.getAccount())); + return Result.ok(loginUserInfoVO); + } + + @AutoLog(value = "加入套装") + @ApiOperation(value = "加入套装", notes = "加入套装") + @PostMapping(value = "/addSuit") + public Result addSuit(@RequestBody @Validated AddSuitDTO addSuitDTO) { + return sysFileService.addSuit(addSuitDTO); + } + +// @AutoLog(value = "查看试穿历史数据") + @ApiOperation(value = "查看试穿历史数据", notes = "查看试穿历史数据") + @PostMapping(value = "/getTryOnHistory") + public Result getTryOnHistory() { + return sysFileService.getTryOnHistory(); + } + + + @AutoLog(value = "上传模特头像") + @ApiOperation(value = "上传模特头像", notes = "上传模特头像") + @PostMapping(value = "/uploadModel") + public Result uploadModel(@RequestParam("file") MultipartFile file, @RequestParam("sex") String sex) throws IOException { + return sysFileService.uploadModel(file, sex); + } + + @AutoLog(value = "获取模特列表") + @ApiOperation(value = "获取模特列表", notes = "获取模特列表") + @PostMapping(value = "/getModelList") + public Result getModelList(@RequestBody @Validated GetModelDTO getModelDTO) { + return sysFileService.getModelList(getModelDTO); + } + + @AutoLog(value = "衣服类型图片所有数据查询") + @ApiOperation(value = "衣服类型图片所有数据查询", notes = "衣服类型图片所有数据查询") + @PostMapping(value = "/list") + public Result queryClothTypeList(@RequestBody @Validated QueryClothTypeDTO queryClothTypeDTO) { + return sysFileService.clothList(queryClothTypeDTO); + } + + @AutoLog(value = "抓取图片") + @ApiOperation(value = "抓取图片", notes = "抓取图片") + @PostMapping(value = "/grabPicture") + public Result grabPicture(@RequestBody @Validated CrawlerPictureDTO crawlerPictureDTO) { + return sysFileService.grabPicture(crawlerPictureDTO.getGrabUrl()); + } + + @AutoLog(value = "取消加入") + @ApiOperation(value = "取消加入", notes = "取消加入") + @PostMapping(value = "/unJoin") + public Result unJoin(@RequestBody @Validated UnJoinDTO unJoinDTO) { + return sysFileService.unJoin(unJoinDTO); + } + + + @AutoLog(value = "加入衣橱") + @ApiOperation(value = "加入衣橱", notes = "加入衣橱") + @PostMapping(value = "/addWardrobe") + public Result addWardrobe(@RequestBody @Validated AddWardrobeDTO addWardrobeDTO) { + return sysFileService.addWardrobe(addWardrobeDTO); + } + + + @AutoLog(value = "提交公司信息") + @ApiOperation(value = "提交公司信息", notes = "提交公司信息") + @PostMapping(value = "/submitContactInfo") + public Result submitContactInfo(@RequestBody @Validated SubmitContactInfoDTO submitContactInfoDTO) { + return sysContactService.submitContactInfo(submitContactInfoDTO); + } + + + @AutoLog(value = "删除衣服或者模特") + @ApiOperation(value = "删除衣服或者模特", notes = "删除衣服或者模特") + @PostMapping(value = "/deleteCloth") + public Result deleteCloth(@RequestBody @Validated DeleteClothDTO deleteClothDTO) { + String taskId = UUID.randomUUID().toString(); + String id = deleteClothDTO.getId(); + SysFile sysFile = sysFileService.getById(id); + if (sysFile == null) { + return Result.error("数据库中无此数据", taskId); + } + String commonClothType = sysFile.getCommonClothType(); + if (oConvertUtils.isNotEmpty(commonClothType) && commonClothType.contains("in_")) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + if (!loginUser.getRoleType().equals("admin")) { + return Result.error("公共文件不能删除!", taskId); + } + } + sysFileService.removeById(id); + + String materialPath = sysFile.getMaterialPath(); + if (oConvertUtils.isNotEmpty(materialPath)) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getMaterialPath, materialPath); + List deleteList = sysFileService.list(queryWrapper); + if (deleteList != null && deleteList.size() > 0) { + log.info("需要删除的数据 deleteList =" + deleteList); + sysFileService.removeBatchByIds(deleteList); + } + } + return Result.OK("删除成功!", taskId); + } + + @AutoLog(value = "上次训练时间") + @ApiOperation(value = "上次训练时间", notes = "上次训练时间") + @PostMapping(value = "/getCostTime") + public Result getCostTime() { + return mwTrainTaskService.getCostTime(); + } + + @AutoLog(value = "换装回调接口") + @ApiOperation(value = "回调接口", notes = "回调接口") + @PostMapping(value = "/tryOnCallBack") + public Result tryOnCallBack(@RequestBody TryOnCallBackDTO tryOnCallBackDTO) { + return sysFileService.tryOnCallBack(tryOnCallBackDTO); + } + + @AutoLog(value = "上传衣服回调接口") + @ApiOperation(value = "上传衣服回调接口", notes = "上传衣服回调接口") + @PostMapping(value = "/callBack") + public Result callBack(@RequestBody CallBackDTO callBackDTO) { + return sysFileService.callBack(callBackDTO); + } + + @AutoLog(value = "试穿") + @ApiOperation(value = "试穿", notes = "试穿") + @PostMapping(value = "/tryOn") + public Result tryOn(@RequestBody @Validated TryOnDTO tryOnDTO) { + return sysFileService.tryOn(tryOnDTO); + } + + @AutoLog(value = "添加上衣") + @ApiOperation(value = "添加上衣", notes = "添加上衣") + @PostMapping(value = "/uploadClothFile") + public Result uploadClothFile(MultipartFile file) { + return sysFileService.uploadFileCloth(file); + } + + // @AutoLog(value = "批量添加上衣") + @ApiOperation(value = "批量添加上衣", notes = "批量添加上衣") + @PostMapping(value = "/batchUploadClothFile") + public Result batchUploadClothFile(MultipartFile[] files) { + return sysFileService.batchUploadClothFile(files); + } + + @AutoLog(value = "上传图片分类") + @ApiOperation(value = "上传图片分类", notes = "上传图片分类") + @PostMapping(value = "/uploadCloth") + public Result uploadCloth(@RequestBody UploadClothDTO uploadClothDTO) { + return sysFileService.uploadCloth(uploadClothDTO); + } +/////////////////////////////////////////////////////////////////////////////////////////////////////////// + + /** + * 用户信息 + * + * @param sysUser + * @param result + * @return + */ + private Result userInfo(DpUser sysUser, Result result) { + String username = sysUser.getAccount(); + String syspassword = sysUser.getPassword(); + // 获取用户部门信息 + JSONObject obj = new JSONObject(); + // 生成token + String token = JwtUtil.sign(username, syspassword); + // 设置token缓存有效时间 + redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); + redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); + obj.put("token", token); + obj.put("userInfo", sysUser); + result.setResult(obj); + result.success("登录成功"); + return result; + } + + + @AutoLog(value = "手机号登录接口") + @ApiOperation("手机号登录接口") + @PostMapping("/phoneLogin") + public Result phoneLogin(@RequestBody PhoneLoginDTO phoneLoginDTO) { + Result result = new Result(); + String phone = phoneLoginDTO.getPhone(); + //查看验证码是否正确 + String smscode = phoneLoginDTO.getCaptcha(); + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone; + Object code = redisUtil.get(redisKey); + //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + if (!smscode.equals(code)) { + log.info("手机验证码=" + code); + result.setCode(500); + result.setSuccess(false); + result.setMessage("手机验证码错误"); + return result; + } + DpUser sysUser = dpUserService.getUserByAccount(phone); + if (null == sysUser) { + sysUser = dpUserService.addUser(phone); + } + //用户信息 + userInfo(sysUser, result); + //添加日志 + baseCommonService.addLog("用户名: " + sysUser.getAccount() + ",登录成功!", CommonConstant.LOG_TYPE_1, null); + return result; + } + + + @AutoLog(value = "发送短信验证码") + @ApiOperation("发送短信验证码") + @PostMapping(value = "/sms") + public Result sms(@RequestBody SmsLoginDTO smsLoginDTO) { + String mobile = smsLoginDTO.getPhone(); + log.info(mobile); + if (oConvertUtils.isEmpty(mobile)) { + return Result.error("手机号不允许为空"); + } + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + mobile; + Object object = redisUtil.get(redisKey); + //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + if (object != null) { + return Result.error("验证码2分钟内,仍然有效!"); + } + //随机数 + String captcha = RandomUtil.randomNumbers(6); + JSONObject obj = new JSONObject(); + obj.put("code", captcha); + try { + boolean b = false; + //登录模板 + b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.LOGIN_TEMPLATE_CODE); + if (b == false) { + return Result.error("短信验证码发送失败,请稍后重试!"); + } + //update-begin-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + //验证码10分钟内有效 + redisUtil.set(redisKey, captcha, 120); + //update-end-author:taoyan date:2022-9-13 for: VUEN-2245 【漏洞】发现新漏洞待处理20220906 + //update-begin--Author:scott Date:20190812 for:issues#391 + //result.setResult(captcha); + //update-end--Author:scott Date:20190812 for:issues#391 + //查看数据库中是否有改用户,如果没有,则新增用户 + dpUserService.addUser(mobile); + return Result.OK("发送成功!"); + } catch (ClientException e) { + return Result.error("短信接口未配置,请联系管理员!"); + } + } + + +} diff --git a/digital-application/src/main/java/digital/application/controller/TjSwapHairController.java b/digital-application/src/main/java/digital/application/controller/TjSwapHairController.java new file mode 100644 index 0000000..03118cf --- /dev/null +++ b/digital-application/src/main/java/digital/application/controller/TjSwapHairController.java @@ -0,0 +1,112 @@ +package digital.application.controller; + + +import digital.application.dto.tjHair.GetHairDataDTO; +import digital.application.dto.tjHair.GetSwapHairHistoryByTaskIdDTO; +import digital.application.service.ISysFileService; +import digital.base.annotation.AutoLog; +import digital.base.vo.Result; +import digital.bean.task.DpUser; +import digital.system.jeecg.system.service.IDpUserService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +@Api(tags = "给第三方提供接口") +@RestController +@RequestMapping("/api/v1") +@Slf4j +public class TjSwapHairController { + + @Autowired + private ISysFileService sysFileService; + @Autowired + private IDpUserService dpUserService; + + @AutoLog(value = "第三方-根据账号查询可以换发型的数据") + @ApiOperation(value = "第三方-根据账号查询可以换发型的数据", notes = "第三方-根据账号查询可以换发型的数据") + @PostMapping(value = "/getHairData") + public Result getHairData(@RequestBody @Validated GetHairDataDTO getHairData) { + String phone = "18701620166"; + DpUser dpUser = dpUserService.getUserByAccount(phone); + log.info("第三方用户信息:{}", dpUser); + getHairData.setUserId(dpUser.getId()); + return sysFileService.getHairData(getHairData); + } + + @AutoLog(value = "第三方-根据手机账号查询可以换发型的数据") + @ApiOperation(value = "第三方-根据手机账号查询可以换发型的数据", notes = "第三方-根据手机账号查询可以换发型的数据") + @PostMapping(value = "/queryHairData") + public Result queryHairData(@RequestBody @Validated GetHairDataDTO getHairData) { + String phone = getHairData.getPhone(); + DpUser dpUser = dpUserService.getUserByAccount(phone); + log.info("查询的第三方用户信息:{}", dpUser); + getHairData.setUserId(dpUser.getId()); + return sysFileService.getHairData(getHairData); + } + + @ApiOperation(value = "第三方-试穿发型", notes = "第三方-试穿发型") + @PostMapping(value = "/swapHair") + public Result swapHair(@RequestParam(value = "isHr") String isHr, + @RequestParam(value = "hairIds") String hairIds, + MultipartFile[] files, + @RequestParam(value = "sex") String sex) { + //判断手机号格式是否合法 + String phone = "18701620166"; + //首先判断用户是否存在,不存在则添加 + DpUser dpUser = dpUserService.getUserByAccount(phone); + return sysFileService.swapHair(dpUser, isHr, hairIds, files, sex); + } + + + @ApiOperation(value = "第三方第二家-试穿发型", notes = "第三方第二家-试穿发型") + @PostMapping(value = "/swapHairAsync") + public Result swapHairAsync(@RequestParam(value = "isHr") String isHr, + @RequestParam(value = "hairIds") String hairIds, + MultipartFile[] files, + @RequestParam(value = "modelUrls") String modelUrls, + @RequestParam(value = "sex") String sex) { + //判断手机号格式是否合法 + String phone = "13763009010"; + //首先判断用户是否存在,不存在则添加 + DpUser dpUser = dpUserService.getUserByAccount(phone); + return sysFileService.swapHairAsync(dpUser, isHr, hairIds, files, modelUrls, sex); + } + + @AutoLog(value = "查看换发结果数据") + @ApiOperation(value = "查看换发结果数据", notes = "查看换发结果数据") + @PostMapping(value = "/getSwapHairHistory") + public Result getSwapHairHistory() { + String phone = "18701620166"; + DpUser dpUser = dpUserService.getUserByAccount(phone); + return sysFileService.getSwapHairHistory(dpUser); + } + + @AutoLog(value = "查看换发结果数据") + @ApiOperation(value = "查看换发结果数据", notes = "查看换发结果数据") + @PostMapping(value = "/getSwapHairHistoryByTaskId") + public Result getSwapHairHistoryByTaskId(@RequestBody @Validated GetSwapHairHistoryByTaskIdDTO getSwapHairHistoryByTaskIdDTO) { + return sysFileService.getSwapHairHistoryByTaskId(getSwapHairHistoryByTaskIdDTO.getTaskId()); + } + + @ApiOperation(value = "查看固定手机号试穿历史数据", notes = "查看固定手机号试穿历史数据") + @PostMapping(value = "/getTargetTryOnHistory") + public Result getTargetTryOnHistory() { + String phone = "13763009010"; + DpUser dpUser = dpUserService.getUserByAccount(phone); + return sysFileService.getTargetTryOnHistory(dpUser); + } + + @AutoLog(value = "查看第二家公司换发结果数据") + @ApiOperation(value = "查看第二家公司换发结果数据", notes = "查看第二家公司换发结果数据") + @PostMapping(value = "/querySwapHairHistory") + public Result querySwapHairHistory() { + String phone = "13763009010"; + DpUser dpUser = dpUserService.getUserByAccount(phone); + return sysFileService.getSwapHairHistory(dpUser); + } +} diff --git a/digital-application/src/main/java/digital/application/dto/AddRoomClothDTO.java b/digital-application/src/main/java/digital/application/dto/AddRoomClothDTO.java new file mode 100644 index 0000000..da5b702 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/AddRoomClothDTO.java @@ -0,0 +1,15 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AddRoomClothDTO { + + @NotBlank(message = "roomId 不能为空!") + private String roomId; + + @NotBlank(message = "clothId 不能为空!") + private String clothId; +} diff --git a/digital-application/src/main/java/digital/application/dto/AddRoomDTO.java b/digital-application/src/main/java/digital/application/dto/AddRoomDTO.java new file mode 100644 index 0000000..352db65 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/AddRoomDTO.java @@ -0,0 +1,19 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AddRoomDTO { + + @ApiModelProperty(value = "专题试衣间名称") + @NotBlank(message = "roomName 不能为空!") + private String roomName; + + @ApiModelProperty(value = "专题试衣间名称") + @NotBlank(message = "sex 不能为空!") + private String sex; + +} diff --git a/digital-application/src/main/java/digital/application/dto/AddSuitDTO.java b/digital-application/src/main/java/digital/application/dto/AddSuitDTO.java new file mode 100644 index 0000000..7a473e8 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/AddSuitDTO.java @@ -0,0 +1,18 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AddSuitDTO { + + @ApiModelProperty(value = "上衣") + @NotBlank(message = "topClothId 不能为空!") + private String topClothId; + + @ApiModelProperty(value = "下衣") + @NotBlank(message = "bottomClothId 不能为空!") + private String bottomClothId; +} diff --git a/digital-application/src/main/java/digital/application/dto/AddWardrobeDTO.java b/digital-application/src/main/java/digital/application/dto/AddWardrobeDTO.java new file mode 100644 index 0000000..15eef6a --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/AddWardrobeDTO.java @@ -0,0 +1,18 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class AddWardrobeDTO { + + @ApiModelProperty(value = " topCloth 上衣 bottomCloth 下衣 dress suit 套装 ") + @NotBlank(message = "clothType 不能为空!") + private String clothType; + + @ApiModelProperty(value = "衣服id") + @NotBlank(message = "clothId 不能为空!") + private String clothId; +} diff --git a/digital-application/src/main/java/digital/application/dto/BatchDelHistoryDTO.java b/digital-application/src/main/java/digital/application/dto/BatchDelHistoryDTO.java new file mode 100644 index 0000000..73134a3 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/BatchDelHistoryDTO.java @@ -0,0 +1,13 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class BatchDelHistoryDTO { + + @NotEmpty + private List historyIds; +} diff --git a/digital-application/src/main/java/digital/application/dto/BuyLinksDTO.java b/digital-application/src/main/java/digital/application/dto/BuyLinksDTO.java new file mode 100644 index 0000000..2e11da4 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/BuyLinksDTO.java @@ -0,0 +1,19 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class BuyLinksDTO { + + @ApiModelProperty(value = "衣服id") + @NotBlank(message = "clothId 不能为空!") + private String clothId; + + @ApiModelProperty(value = "购买链接") + @NotBlank(message = "buyLinks 不能为空!") + private String buyLink; + +} diff --git a/digital-application/src/main/java/digital/application/dto/CallBackDTO.java b/digital-application/src/main/java/digital/application/dto/CallBackDTO.java new file mode 100644 index 0000000..c54570c --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/CallBackDTO.java @@ -0,0 +1,18 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class CallBackDTO { + + @ApiModelProperty(value = "任务状态 0 成功 -1 失败") + private String status; + + @ApiModelProperty(value = "任务id") + private String taskId; + + @ApiModelProperty(value = "衣服id") + private String clothId; + +} diff --git a/digital-application/src/main/java/digital/application/dto/CrawlerPictureDTO.java b/digital-application/src/main/java/digital/application/dto/CrawlerPictureDTO.java new file mode 100644 index 0000000..7c2da38 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/CrawlerPictureDTO.java @@ -0,0 +1,8 @@ +package digital.application.dto; + +import lombok.Data; + +@Data +public class CrawlerPictureDTO { + private String grabUrl; +} diff --git a/digital-application/src/main/java/digital/application/dto/DelRoomDTO.java b/digital-application/src/main/java/digital/application/dto/DelRoomDTO.java new file mode 100644 index 0000000..4bdc04b --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/DelRoomDTO.java @@ -0,0 +1,12 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class DelRoomDTO { + + @NotBlank(message = "roomId 不能为空!") + private String roomId; +} diff --git a/digital-application/src/main/java/digital/application/dto/DeleteClothDTO.java b/digital-application/src/main/java/digital/application/dto/DeleteClothDTO.java new file mode 100644 index 0000000..363f27d --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/DeleteClothDTO.java @@ -0,0 +1,12 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class DeleteClothDTO { + + @NotBlank(message = "id不能为空!") + private String id; +} diff --git a/digital-application/src/main/java/digital/application/dto/GetModelDTO.java b/digital-application/src/main/java/digital/application/dto/GetModelDTO.java new file mode 100644 index 0000000..99f85ad --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/GetModelDTO.java @@ -0,0 +1,12 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetModelDTO { + + @NotBlank(message = "性别不能为空!") + private String sex; +} diff --git a/digital-application/src/main/java/digital/application/dto/GetRoomClothListDTO.java b/digital-application/src/main/java/digital/application/dto/GetRoomClothListDTO.java new file mode 100644 index 0000000..7c44417 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/GetRoomClothListDTO.java @@ -0,0 +1,17 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetRoomClothListDTO { + + @NotBlank(message = "roomId 不能为空!") + private String roomId; + + @ApiModelProperty(value = "性别") + @NotBlank(message = "sex 不能为空!") + private String sex; +} diff --git a/digital-application/src/main/java/digital/application/dto/GetRoomListDTO.java b/digital-application/src/main/java/digital/application/dto/GetRoomListDTO.java new file mode 100644 index 0000000..98d6d2b --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/GetRoomListDTO.java @@ -0,0 +1,12 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetRoomListDTO { + + @NotBlank(message = "sex 不能为空!") + private String sex; +} diff --git a/digital-application/src/main/java/digital/application/dto/LoginDTO.java b/digital-application/src/main/java/digital/application/dto/LoginDTO.java new file mode 100644 index 0000000..9326412 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/LoginDTO.java @@ -0,0 +1,14 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class LoginDTO { + + @ApiModelProperty(value = "账号") + @NotBlank(message = "account 不能为空!") + private String account; +} diff --git a/digital-application/src/main/java/digital/application/dto/PhoneLoginDTO.java b/digital-application/src/main/java/digital/application/dto/PhoneLoginDTO.java new file mode 100644 index 0000000..8883666 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/PhoneLoginDTO.java @@ -0,0 +1,24 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +/** + * author: damao + * date:2022-10-03 12:47 + * description:手机号登录dto + **/ +@Data +public class PhoneLoginDTO { + + @NotBlank(message = "手机号不能为空!") + @ApiModelProperty(value = "手机号") + private String phone; + + @NotBlank(message = "验证码不能为空!") + @ApiModelProperty(value = "验证码") + private String captcha; + +} diff --git a/digital-application/src/main/java/digital/application/dto/QueryClothTypeDTO.java b/digital-application/src/main/java/digital/application/dto/QueryClothTypeDTO.java new file mode 100644 index 0000000..3cba463 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/QueryClothTypeDTO.java @@ -0,0 +1,21 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class QueryClothTypeDTO { + + @ApiModelProperty(value = "衣服库 no 我的衣橱 yes") + @NotBlank(message = "isPerson 不能为空!") + private String isPerson; + + @ApiModelProperty(value = " topCloth 上衣 bottomCloth 下衣 dress suit 套装 excludeSuit 除了套装 ") + private String clothType; + + @ApiModelProperty(value = "性别") + private String sex; + +} diff --git a/digital-application/src/main/java/digital/application/dto/SmsLoginDTO.java b/digital-application/src/main/java/digital/application/dto/SmsLoginDTO.java new file mode 100644 index 0000000..57b8458 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/SmsLoginDTO.java @@ -0,0 +1,15 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class SmsLoginDTO { + + @ApiModelProperty(value = "手机号") + @NotBlank(message = "手机号不能为空!") + private String phone; + +} diff --git a/digital-application/src/main/java/digital/application/dto/SubmitContactInfoDTO.java b/digital-application/src/main/java/digital/application/dto/SubmitContactInfoDTO.java new file mode 100644 index 0000000..cffa990 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/SubmitContactInfoDTO.java @@ -0,0 +1,25 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class SubmitContactInfoDTO { + + @ApiModelProperty(value = "姓名") + @NotBlank(message = "name 不能为空!") + private String name; + + @ApiModelProperty(value = "手机号") + @NotBlank(message = "phone 不能为空!") + private String phone; + + @ApiModelProperty(value = "公司") + @NotBlank(message = "company 不能为空!") + private String company; + + @ApiModelProperty(value = "需求描述") + private String description; +} diff --git a/digital-application/src/main/java/digital/application/dto/TrainTaskCallbackDTO.java b/digital-application/src/main/java/digital/application/dto/TrainTaskCallbackDTO.java new file mode 100644 index 0000000..39cb541 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/TrainTaskCallbackDTO.java @@ -0,0 +1,20 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class TrainTaskCallbackDTO { + + @ApiModelProperty(value = "状态") + private String status; + + @ApiModelProperty(value = "taskId") + private String taskId; + + @ApiModelProperty(value = "urlList") + private List urlList; + +} diff --git a/digital-application/src/main/java/digital/application/dto/TryOnCallBackDTO.java b/digital-application/src/main/java/digital/application/dto/TryOnCallBackDTO.java new file mode 100644 index 0000000..28bd62c --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/TryOnCallBackDTO.java @@ -0,0 +1,21 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class TryOnCallBackDTO { + + @ApiModelProperty(value = "任务状态") + private Integer status; + + @ApiModelProperty(value = "任务id") + private String taskId; + + @ApiModelProperty(value = "衣服路径") + private String filePath; + + @ApiModelProperty(value = "衣服路径") + private String msg; + +} diff --git a/digital-application/src/main/java/digital/application/dto/TryOnDTO.java b/digital-application/src/main/java/digital/application/dto/TryOnDTO.java new file mode 100644 index 0000000..acc05fd --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/TryOnDTO.java @@ -0,0 +1,25 @@ +package digital.application.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +public class TryOnDTO { + + private List tryOnList; + + private String isHr; + + @Data + @AllArgsConstructor + @NoArgsConstructor + public static class TryOn { + + private List clothIds; + + private String modelId; + } +} diff --git a/digital-application/src/main/java/digital/application/dto/UnJoinDTO.java b/digital-application/src/main/java/digital/application/dto/UnJoinDTO.java new file mode 100644 index 0000000..867752c --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/UnJoinDTO.java @@ -0,0 +1,15 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class UnJoinDTO { + + @ApiModelProperty(value = "衣服id") + @NotBlank(message = "clothId 不能为空!") + private String clothId; + +} diff --git a/digital-application/src/main/java/digital/application/dto/UnTryOnDTO.java b/digital-application/src/main/java/digital/application/dto/UnTryOnDTO.java new file mode 100644 index 0000000..429b9b2 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/UnTryOnDTO.java @@ -0,0 +1,14 @@ +package digital.application.dto; + +import lombok.Data; + +import javax.validation.constraints.NotEmpty; +import java.util.List; + +@Data +public class UnTryOnDTO { + + @NotEmpty + private List historyIds; + +} diff --git a/digital-application/src/main/java/digital/application/dto/UpdateRoomDTO.java b/digital-application/src/main/java/digital/application/dto/UpdateRoomDTO.java new file mode 100644 index 0000000..90f704d --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/UpdateRoomDTO.java @@ -0,0 +1,17 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class UpdateRoomDTO { + + @NotBlank(message = "roomId 不能为空!") + private String roomId; + + @ApiModelProperty(value = "专题试衣间名称") + @NotBlank(message = "roomName 不能为空!") + private String roomName; +} diff --git a/digital-application/src/main/java/digital/application/dto/UploadClothDTO.java b/digital-application/src/main/java/digital/application/dto/UploadClothDTO.java new file mode 100644 index 0000000..151c98d --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/UploadClothDTO.java @@ -0,0 +1,23 @@ +package digital.application.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; +import java.util.List; + +@Data +public class UploadClothDTO { + + private List clothFileList; + + @NotBlank(message = "clothType不能为空!") + private String clothType; + + @ApiModelProperty(value = "是否同步 yes 同步 no 不同步 ") + @NotBlank(message = "isSync 不能为空!") + private String isSync; + + @NotBlank(message = "sex 不能为空!") + private String sex; +} diff --git a/digital-application/src/main/java/digital/application/dto/UserHistoryMap.java b/digital-application/src/main/java/digital/application/dto/UserHistoryMap.java new file mode 100644 index 0000000..1ac43c7 --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/UserHistoryMap.java @@ -0,0 +1,21 @@ +package digital.application.dto; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@Data +public class UserHistoryMap { + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + private String batchNo; + + private String historyIdFileUrls; + +} diff --git a/digital-application/src/main/java/digital/application/dto/tjHair/GetHairDataDTO.java b/digital-application/src/main/java/digital/application/dto/tjHair/GetHairDataDTO.java new file mode 100644 index 0000000..a64d8ee --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/tjHair/GetHairDataDTO.java @@ -0,0 +1,22 @@ +package digital.application.dto.tjHair; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetHairDataDTO { + +// @NotBlank(message = "phone 不能为空!") +// @Pattern(regexp = "^1[3-9]\\d{9}$", message = "phone 不是合法的手机号!") + @ApiModelProperty(value = "手机号码") + private String phone; + + @ApiModelProperty(value = "是否个人衣柜") + @NotBlank(message = "isPerson 不能为空!") + private String isPerson; + + @ApiModelProperty(value = "用户id 前端不用传") + private String userId; +} diff --git a/digital-application/src/main/java/digital/application/dto/tjHair/GetSwapHairHistoryByTaskIdDTO.java b/digital-application/src/main/java/digital/application/dto/tjHair/GetSwapHairHistoryByTaskIdDTO.java new file mode 100644 index 0000000..089e6af --- /dev/null +++ b/digital-application/src/main/java/digital/application/dto/tjHair/GetSwapHairHistoryByTaskIdDTO.java @@ -0,0 +1,12 @@ +package digital.application.dto.tjHair; + +import lombok.Data; + +import javax.validation.constraints.NotBlank; + +@Data +public class GetSwapHairHistoryByTaskIdDTO { + + @NotBlank(message = "taskId 不能为空!") + private String taskId; +} diff --git a/digital-application/src/main/java/digital/application/emun/LiveStatusEnum.java b/digital-application/src/main/java/digital/application/emun/LiveStatusEnum.java new file mode 100644 index 0000000..b97ee43 --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/LiveStatusEnum.java @@ -0,0 +1,31 @@ +package digital.application.emun; + +import java.io.IOException; + +public enum LiveStatusEnum { + //枚举值 + //STARTING 开启中 + //SUCCESS 开播成功 + //CANCEL 取消开播 + //FAIL 开播失败 + //说明 + CANCEL, FAIL, STARTING, SUCCESS; + + public String toValue() { + switch (this) { + case CANCEL: return "CANCEL"; + case FAIL: return "FAIL"; + case STARTING: return "STARTING"; + case SUCCESS: return "SUCCESS"; + } + return null; + } + + public static LiveStatusEnum forValue(String value) throws IOException { + if (value.equals("CANCEL")) return CANCEL; + if (value.equals("FAIL")) return FAIL; + if (value.equals("STARTING")) return STARTING; + if (value.equals("SUCCESS")) return SUCCESS; + throw new IOException("Cannot deserialize Status"); + } +} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/emun/ReplySource.java b/digital-application/src/main/java/digital/application/emun/ReplySource.java new file mode 100644 index 0000000..e1b3bc6 --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/ReplySource.java @@ -0,0 +1,25 @@ +package digital.application.emun; + + +import java.io.IOException; + +/** + * 回复者 主播 ANCHOR, 助播 ASSISTANT; + */ +public enum ReplySource { + ANCHOR, ASSISTANT; + + public String toValue() { + switch (this) { + case ANCHOR: return "ANCHOR"; + case ASSISTANT: return "ASSISTANT"; + } + return null; + } + + public static ReplySource forValue(String value) throws IOException { + if (value.equals("ANCHOR")) return ANCHOR; + if (value.equals("ASSISTANT")) return ASSISTANT; + throw new IOException("Cannot deserialize ReplySource"); + } +} diff --git a/digital-application/src/main/java/digital/application/emun/ReplyType.java b/digital-application/src/main/java/digital/application/emun/ReplyType.java new file mode 100644 index 0000000..5013f4c --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/ReplyType.java @@ -0,0 +1,21 @@ +package digital.application.emun; + +import java.io.IOException; + +public enum ReplyType { + AUDIO, TEXT; + + public String toValue() { + switch (this) { + case AUDIO: return "AUDIO"; + case TEXT: return "TEXT"; + } + return null; + } + + public static ReplyType forValue(String value) throws IOException { + if (value.equals("AUDIO")) return AUDIO; + if (value.equals("TEXT")) return TEXT; + throw new IOException("Cannot deserialize ReplyType"); + } +} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/emun/SortTypeEnum.java b/digital-application/src/main/java/digital/application/emun/SortTypeEnum.java new file mode 100644 index 0000000..12e909f --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/SortTypeEnum.java @@ -0,0 +1,49 @@ +package digital.application.emun; + + +import io.swagger.models.auth.In; + +public enum SortTypeEnum { + picture_1("1", "DESC"), + picture_2("0", "ASC"), + ; + + SortTypeEnum(String type, String extendName) { + this.type = type; + this.extendName = extendName; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getExtendName() { + return extendName; + } + + public void setExtendName(String extendName) { + this.extendName = extendName; + } + + private String type; + private String extendName; + + + public static SortTypeEnum codeIn(String type) { + if (type == null) { + return null; + } else { + for (SortTypeEnum em : SortTypeEnum.values()) { + if (em.getType().equals(type)) { + return em; + } + } + return null; + } + } + +} diff --git a/digital-application/src/main/java/digital/application/emun/StatusTypeEnum.java b/digital-application/src/main/java/digital/application/emun/StatusTypeEnum.java new file mode 100644 index 0000000..9b2024a --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/StatusTypeEnum.java @@ -0,0 +1,56 @@ +package digital.application.emun; + + +/** + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/7/13! + */ +public enum StatusTypeEnum { + picture_1("2", "DRAFT"), + picture_2("0", "IN_PROGRESS"), + picture_3("1", "SUCCESS"), + picture_4("-1", "FAIL"), + ; + + StatusTypeEnum(String fileType, String extendName) { + this.fileType = fileType; + this.extendName = extendName; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public String getExtendName() { + return extendName; + } + + public void setExtendName(String extendName) { + this.extendName = extendName; + } + + private String fileType; + private String extendName; + + + public static StatusTypeEnum codeIn(String fileType) { + if (fileType == null) { + return null; + } else { + for (StatusTypeEnum em : StatusTypeEnum.values()) { + if (em.getFileType().equals(fileType)) { + return em; + } + } + return null; + } + } + +} diff --git a/digital-application/src/main/java/digital/application/emun/Type.java b/digital-application/src/main/java/digital/application/emun/Type.java new file mode 100644 index 0000000..ff58821 --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/Type.java @@ -0,0 +1,31 @@ +package digital.application.emun; + +import java.io.IOException; + +public enum Type { + GIFT, KEYS, LIVE_DURATION, LIVE_INTERVAL, ONLINE_NUM, TOTAL_VIEW_NUM, UPVOTE_NUM; + + public String toValue() { + switch (this) { + case GIFT: return "GIFT"; + case KEYS: return "KEYS"; + case LIVE_DURATION: return "LIVE_DURATION"; + case LIVE_INTERVAL: return "LIVE_INTERVAL"; + case ONLINE_NUM: return "ONLINE_NUM"; + case TOTAL_VIEW_NUM: return "TOTAL_VIEW_NUM"; + case UPVOTE_NUM: return "UPVOTE_NUM"; + } + return null; + } + + public static Type forValue(String value) throws IOException { + if (value.equals("GIFT")) return GIFT; + if (value.equals("KEYS")) return KEYS; + if (value.equals("LIVE_DURATION")) return LIVE_DURATION; + if (value.equals("LIVE_INTERVAL")) return LIVE_INTERVAL; + if (value.equals("ONLINE_NUM")) return ONLINE_NUM; + if (value.equals("TOTAL_VIEW_NUM")) return TOTAL_VIEW_NUM; + if (value.equals("UPVOTE_NUM")) return UPVOTE_NUM; + throw new IOException("Cannot deserialize Type"); + } +} diff --git a/digital-application/src/main/java/digital/application/emun/TypeEnum.java b/digital-application/src/main/java/digital/application/emun/TypeEnum.java new file mode 100644 index 0000000..f689813 --- /dev/null +++ b/digital-application/src/main/java/digital/application/emun/TypeEnum.java @@ -0,0 +1,23 @@ +package digital.application.emun; + +import java.io.IOException; + +public enum TypeEnum { + GLOBAL_IMAGE, IMAGE, VIDEO; + + public String toValue() { + switch (this) { + case GLOBAL_IMAGE: return "GlobalImage"; + case IMAGE: return "Image"; + case VIDEO: return "Video"; + } + return null; + } + + public static TypeEnum forValue(String value) throws IOException { + if (value.equals("GlobalImage")) return GLOBAL_IMAGE; + if (value.equals("Image")) return IMAGE; + if (value.equals("Video")) return VIDEO; + throw new IOException("Cannot deserialize TypeEnum"); + } +} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/entity/SysContact.java b/digital-application/src/main/java/digital/application/entity/SysContact.java new file mode 100644 index 0000000..65acbbf --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysContact.java @@ -0,0 +1,94 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: sys_contact + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Data +@TableName("sys_contact") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_contact对象", description = "sys_contact") +public class SysContact implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + /** + * 姓名 + */ + @Excel(name = "姓名", width = 15) + @ApiModelProperty(value = "姓名") + private String name; + /** + * 手机号 + */ + @Excel(name = "手机号", width = 15) + @ApiModelProperty(value = "手机号") + private String phone; + /** + * 公司 + */ + @Excel(name = "公司", width = 15) + @ApiModelProperty(value = "公司") + private String company; + /** + * 需求描述 + */ + @Excel(name = "需求描述", width = 15) + @ApiModelProperty(value = "需求描述") + private String description; + /** + * 逻辑删 + */ + @Excel(name = "逻辑删", width = 15) + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/entity/SysFile.java b/digital-application/src/main/java/digital/application/entity/SysFile.java new file mode 100644 index 0000000..bcc1efb --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysFile.java @@ -0,0 +1,168 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_file") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_file对象", description = "sys_file") +public class SysFile implements Serializable { + + private static final long serialVersionUID = 1L; + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "代表值") + private String repValue; + + @ApiModelProperty(value = "衣服库id 记录加入衣橱的时候的id") + private String wardrobeId; + + @ApiModelProperty(value = "购买链接") + private String buyLink; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "素材路径") + private String materialPath; + + @ApiModelProperty(value = "是否个人衣柜") + private String isPerson; + + private String processType; + + @ApiModelProperty(value = "文件状态 enable : 启用 disable :禁用 fail 失败 ") + private String fileStatus; + + @ApiModelProperty(value = "衣服类型 topCloth 上衣\n" + + "bottomCloth 下衣\n" + + "dress 连衣裙\n" + + "发型类型 hair" + + "身材 figure" + + "不全全部展示\n") + private String clothType; + + @ApiModelProperty(value = "文件类型 clothType modelType hairType") + private String fileType; + + @ApiModelProperty(value = "是否公共数据") + private String commonClothType; + + @ApiModelProperty(value = "扩展名") + private String extendName; + + @ApiModelProperty(value = "文件夹下文件个数") + private Integer fileSum; + + @ApiModelProperty(value = "文件名") + private String fileName; + + @Excel(name = "文件路径", width = 15) + @ApiModelProperty(value = "文件路径") + private String ossFilePath; + + + /** + * 文件路径 + */ + @Excel(name = "文件路径", width = 15) + @ApiModelProperty(value = "文件路径") + private String filePath; + /** + * 文件路径id + */ + @Excel(name = "文件路径id", width = 15) + @ApiModelProperty(value = "文件路径id") + private String filePathId; + /** + * 对应ossId + */ + @Excel(name = "对应ossId", width = 15) + @ApiModelProperty(value = "对应ossId") + private String fileOssId; + /** + * 文件名称 + */ + @Excel(name = "文件名称", width = 15) + @ApiModelProperty(value = "文件名称") + private String ossFileName; + /** + * 删除标识(0-未删除,1-已删除) + */ + @Excel(name = "删除标识(0-未删除,1-已删除)", width = 15) + @ApiModelProperty(value = "删除标识(0-未删除,1-已删除)") + @TableLogic + private Integer delFlag; + + /** + * 文件大小 + */ + @Excel(name = "文件大小", width = 15) + @ApiModelProperty(value = "文件大小") + private Integer fileSize; + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; + + @ApiModelProperty(value = "过期时间") + private Integer expireTime; + /** + * 临时数据 1 是,0 不是 + */ + @Excel(name = "临时数据 1 是,0 不是", width = 15) + @ApiModelProperty(value = "临时数据 1 是,0 不是") + private String isTemp; + + + /** + * 用户id + */ + @Excel(name = "用户id", width = 15) + @ApiModelProperty(value = "用户id") + private String userId; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "更新时间") + private Date updateTime; + +} diff --git a/digital-application/src/main/java/digital/application/entity/SysHistory.java b/digital-application/src/main/java/digital/application/entity/SysHistory.java new file mode 100644 index 0000000..33a47c1 --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysHistory.java @@ -0,0 +1,70 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_history") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_history", description = "sys_history") +public class SysHistory implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "试穿类型 单个single 还是批量 batch ") + private String tryOnType; + + @ApiModelProperty(value = "试穿算法 cloth 衣服 hair 发型 ") + private String tryOnAlgo; + + @ApiModelProperty(value = "批次号") + private String batchNo; + + @ApiModelProperty(value = "任务状态") + private String status; + + @ApiModelProperty(value = "批次号") + private String taskId; + + @ApiModelProperty(value = "图片集合") + private String fileUrl; + + @ApiModelProperty(value = "用户id") + private String userId; + + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/entity/SysRoom.java b/digital-application/src/main/java/digital/application/entity/SysRoom.java new file mode 100644 index 0000000..74abde4 --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysRoom.java @@ -0,0 +1,58 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_room") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_room", description = "sys_room") +public class SysRoom implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "专题试衣间名称") + private String roomName; + + @ApiModelProperty(value = "性别") + private String sex; + + @ApiModelProperty(value = "用户id") + private String userId; + + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/entity/SysRoomCloth.java b/digital-application/src/main/java/digital/application/entity/SysRoomCloth.java new file mode 100644 index 0000000..501458a --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysRoomCloth.java @@ -0,0 +1,56 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_room_cloth") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_room_cloth", description = "sys_room_cloth") +public class SysRoomCloth implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "专题试衣间id") + private String roomId; + + @ApiModelProperty(value = "文件id") + private String fileId; + + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/entity/SysTaskQueue.java b/digital-application/src/main/java/digital/application/entity/SysTaskQueue.java new file mode 100644 index 0000000..63aca55 --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysTaskQueue.java @@ -0,0 +1,73 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_task_queue") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_task_queue", description = "sys_task_queue") +public class SysTaskQueue implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.AUTO) + @ApiModelProperty(value = "主键") + private Integer id; + + @ApiModelProperty(value = "是否高清") + private String isHr; + + @ApiModelProperty(value = "试穿类型 单个 single 还是批量 batch ") + private String tryOnType; + + @ApiModelProperty(value = "试穿算法 cloth 衣服 hair 发型 figure 身材 underwear 内衣 ") + private String tryOnAlgo; + + @ApiModelProperty(value = "sex") + private String sex; + + @ApiModelProperty(value = "任务状态") + private String status; + + @ApiModelProperty(value = "批次号") + private String taskId; + + @ApiModelProperty(value = "图片集合") + private String jsonInfo; + + @ApiModelProperty(value = "用户id") + private String userId; + + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/entity/SysWhiteUser.java b/digital-application/src/main/java/digital/application/entity/SysWhiteUser.java new file mode 100644 index 0000000..49656fc --- /dev/null +++ b/digital-application/src/main/java/digital/application/entity/SysWhiteUser.java @@ -0,0 +1,52 @@ +package digital.application.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("sys_white_user") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_white_user", description = "sys_white_user") +public class SysWhiteUser implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + @ApiModelProperty(value = "白名单账号") + private String account; + + @ApiModelProperty(value = "逻辑删") + @TableLogic + private Integer delFlag; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + @ApiModelProperty(value = "更新人") + private String updateBy; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; +} diff --git a/digital-application/src/main/java/digital/application/mapper/MwTrainTaskMapper.java b/digital-application/src/main/java/digital/application/mapper/MwTrainTaskMapper.java new file mode 100644 index 0000000..b7720b6 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/MwTrainTaskMapper.java @@ -0,0 +1,14 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.bean.task.MwTrainTask; + +/** + * @Description: mw_train_task + * @Author: jeecg-boot + * @Date: 2023-10-06 + * @Version: V1.0 + */ +public interface MwTrainTaskMapper extends BaseMapper { + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysContactMapper.java b/digital-application/src/main/java/digital/application/mapper/SysContactMapper.java new file mode 100644 index 0000000..7097cd1 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysContactMapper.java @@ -0,0 +1,8 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.entity.SysContact; + +public interface SysContactMapper extends BaseMapper { + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysFileMapper.java b/digital-application/src/main/java/digital/application/mapper/SysFileMapper.java new file mode 100644 index 0000000..913921f --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysFileMapper.java @@ -0,0 +1,24 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.application.entity.SysFile; +import digital.application.vo.QueryClothTypeListVO; +import org.apache.ibatis.annotations.Param; + +/** + * @Description: sys_file + * @Author: jeecg-boot + * @Date: 2024-04-23 + * @Version: V1.0 + */ +public interface SysFileMapper extends BaseMapper { + + IPage queryClothTypeList(@Param("page") Page page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper); + + SysFile selectWithoutLogicDeleteById(String clothId); + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysHistoryMapper.java b/digital-application/src/main/java/digital/application/mapper/SysHistoryMapper.java new file mode 100644 index 0000000..067a374 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysHistoryMapper.java @@ -0,0 +1,22 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.dto.UserHistoryMap; +import digital.application.entity.SysHistory; + +import java.util.List; + +public interface SysHistoryMapper extends BaseMapper { + + List selectBatchNosFieldValues(String userId); + + + List selectAllBatchNosFieldValues(); + + SysHistory selectHistoryOne(String taskId); + + List getUserHistory(String userId); + + List getAllUserHistory(); + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysRoomClothMapper.java b/digital-application/src/main/java/digital/application/mapper/SysRoomClothMapper.java new file mode 100644 index 0000000..b5d8a5e --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysRoomClothMapper.java @@ -0,0 +1,9 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.entity.SysRoomCloth; + +public interface SysRoomClothMapper extends BaseMapper { + + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysRoomMapper.java b/digital-application/src/main/java/digital/application/mapper/SysRoomMapper.java new file mode 100644 index 0000000..005c204 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysRoomMapper.java @@ -0,0 +1,9 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.entity.SysRoom; + +public interface SysRoomMapper extends BaseMapper { + + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysTaskQueueMapper.java b/digital-application/src/main/java/digital/application/mapper/SysTaskQueueMapper.java new file mode 100644 index 0000000..85cab5f --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysTaskQueueMapper.java @@ -0,0 +1,8 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.entity.SysTaskQueue; + +public interface SysTaskQueueMapper extends BaseMapper { + +} diff --git a/digital-application/src/main/java/digital/application/mapper/SysWhiteUserMapper.java b/digital-application/src/main/java/digital/application/mapper/SysWhiteUserMapper.java new file mode 100644 index 0000000..6b18e46 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/SysWhiteUserMapper.java @@ -0,0 +1,9 @@ +package digital.application.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.application.entity.SysWhiteUser; + +public interface SysWhiteUserMapper extends BaseMapper { + + +} diff --git a/digital-application/src/main/java/digital/application/mapper/xml/MwTrainTaskMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/MwTrainTaskMapper.xml new file mode 100644 index 0000000..ebbb284 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/MwTrainTaskMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysContactMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysContactMapper.xml new file mode 100644 index 0000000..c3e964b --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysContactMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysFileMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysFileMapper.xml new file mode 100644 index 0000000..e2406dc --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysFileMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysHistoryMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysHistoryMapper.xml new file mode 100644 index 0000000..61f3cfb --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysHistoryMapper.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysRoomClothMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysRoomClothMapper.xml new file mode 100644 index 0000000..d945a16 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysRoomClothMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysRoomMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysRoomMapper.xml new file mode 100644 index 0000000..14a8176 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysRoomMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysTaskQueueMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysTaskQueueMapper.xml new file mode 100644 index 0000000..b39712f --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysTaskQueueMapper.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/mapper/xml/SysWhiteUserMapper.xml b/digital-application/src/main/java/digital/application/mapper/xml/SysWhiteUserMapper.xml new file mode 100644 index 0000000..49134e2 --- /dev/null +++ b/digital-application/src/main/java/digital/application/mapper/xml/SysWhiteUserMapper.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/service/AsyncService.java b/digital-application/src/main/java/digital/application/service/AsyncService.java new file mode 100644 index 0000000..6ef072e --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/AsyncService.java @@ -0,0 +1,183 @@ +//package digital.application.service; +// +//import com.alibaba.fastjson.JSONObject; +//import digital.application.dto.TryOnDTO; +//import digital.application.entity.SysFile; +//import digital.application.entity.SysHistory; +//import digital.application.mapper.MwTrainTaskMapper; +//import digital.application.mapper.SysFileMapper; +//import digital.application.mapper.SysHistoryMapper; +//import digital.base.constant.CommonConstant; +//import digital.base.constant.Face3dSeverHTTPConstant; +//import digital.base.constant.ZitaCommonConstant; +//import digital.bean.task.MwTrainTask; +//import digital.config.oss.OssConfiguration; +//import digital.util.oss.OssBootUtil; +//import digital.util.util.RestUtil; +//import digital.util.util.oConvertUtils; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.http.HttpMethod; +//import org.springframework.http.ResponseEntity; +//import org.springframework.scheduling.annotation.Async; +//import org.springframework.stereotype.Component; +// +//import java.io.File; +//import java.util.Arrays; +//import java.util.List; +//import java.util.UUID; +// +//@Component +//@Slf4j +//public class AsyncService { +// @Autowired +// OssConfiguration ossConfiguration; +// @Autowired +// private SysFileMapper sysFileMapper; +// @Autowired +// private MwTrainTaskMapper trainTaskMapper; +// @Autowired +// private SysHistoryMapper sysHistoryMapper; +// +//// @Transactional +// @Async("defaultThreadPoolExecutor") +// public void syncCommon(List sysHistoryList, TryOnDTO tryOns, String userId) { +// String batchNo = UUID.randomUUID().toString(); +// log.info("开始同步任务" + batchNo); +// List tryOnDTOList = tryOns.getTryOnList(); +// ////////////////// 开始处理试穿 ///////////////////// +// for (int i = 0; i < tryOnDTOList.size(); i++) { +// String taskId = UUID.randomUUID().toString(); +// log.info(taskId + "开始处理试穿"); +// TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); +// SysHistory sysHistory = sysHistoryList.get(i); +// String modelId = tryOnDTO.getModelId(); +// SysFile modelImage = sysFileMapper.selectById(modelId); +// if (modelImage == null) { +// log.info(taskId + "数据库中无此数据! modelId=" + modelId); +// continue; +// } +// List clothIds = tryOnDTO.getClothIds(); +// JSONObject jsonObject = new JSONObject(); +// MwTrainTask trainTask = new MwTrainTask(); +// trainTask.setTaskId(taskId); +// trainTask.setUserId(userId); +// trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); +// trainTask.setClothPath(String.join(",", clothIds)); +// trainTaskMapper.insert(trainTask); +// //给历史记录添加taskid +// sysHistory.setTaskId(taskId); +// sysHistoryMapper.updateById(sysHistory); +// //添加完毕 +// int size = clothIds.size(); +// if (size == 1) { +// for (String clothId : clothIds) { +// SysFile clothImage = sysFileMapper.selectById(clothId); +// if (clothImage != null) { +// if ("topCloth".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); +// jsonObject.put("upper", list); +// jsonObject.put("lower", ""); +// } +// if ("bottomCloth".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "1", clothImage.getProcessType()); +// jsonObject.put("upper", ""); +// jsonObject.put("lower", list); +// } +// if ("dress".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "2", clothImage.getProcessType()); +// jsonObject.put("upper", list); +// jsonObject.put("lower", ""); +// } +// } +// } +// } +// if (size == 2) { +// if (clothIds != null && clothIds.size() > 0) { +// for (String clothId : clothIds) { +// SysFile clothImage = sysFileMapper.selectById(clothId); +// if (clothImage != null) { +// if ("topCloth".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); +// jsonObject.put("upper", list); +// } +// if ("bottomCloth".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); +// jsonObject.put("lower", list); +// } +// if ("dress".equals(clothImage.getClothType())) { +// List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); +// jsonObject.put("upper", list); +// jsonObject.put("lower", ""); +// } +// } +// } +// } +// } +// trainTask.setModelPath(modelImage.getFilePath()); +// long startTime = System.currentTimeMillis(); +// JSONObject clothParam = new JSONObject(); +// clothParam.put("task_id", taskId); +// clothParam.put("userImgPath", modelImage.getFilePath()); +// if (oConvertUtils.isNotEmpty(modelImage.getSex())) { +// clothParam.put("sex", modelImage.getSex()); +// } else { +// clothParam.put("sex", "female"); +// } +// clothParam.put("data_dict", jsonObject); +// log.info("算法 clothParam =" + clothParam); +// try { +// String url; +// if (ZitaCommonConstant.sex_male.equals(modelImage.getSex())) { +// url = Face3dSeverHTTPConstant.SWAP_CLOTH_MALE; +// } else { +// url = Face3dSeverHTTPConstant.SWAP_CLOTH; +// } +// ResponseEntity clothResult = RestUtil.zitaRequest(url, +// HttpMethod.POST, null, clothParam, JSONObject.class); +// String clothState = clothResult.getBody().get("status").toString(); +// log.info(taskId + " 返回结果信息成功 ==" + taskId + " clothResult=" + clothResult.getBody()); +// if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { +// trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); +// trainTask.setResult(Face3dSeverHTTPConstant.result_fail); +// trainTask.setRequestResult(String.format("digital cloth 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); +// trainTaskMapper.updateById(trainTask); +// log.info(String.format("digital cloth 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); +// sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); +// sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); +// sysHistoryMapper.updateById(sysHistory); +// continue; +// } +// // 尝试将返回结果转为JSON +// JSONObject resultBody = clothResult.getBody(); +// String imagePath = (String) resultBody.get("data"); +// File file = new File(imagePath); +// String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); +// String fileUrl = OssBootUtil.uploadOssVideo(file, CommonConstant.PUTON_SWAP, newFileName); +// String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); +// log.info("oss 图片 savePath=" + savePath); +// trainTask.setResultImages(savePath); +// trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); +// trainTask.setResult(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); +// long endTime = System.currentTimeMillis(); +// long duration = (endTime - startTime) / 1000; // 除以1000,将毫秒转换为秒 +// trainTask.setCostTime((int) duration); +// trainTaskMapper.updateById(trainTask); +// //替换换装后的照片 +// sysHistory.setFileUrl(savePath); +// sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); +// sysHistoryMapper.updateById(sysHistory); +// } catch (Exception ex) { +// String message = ex.getMessage(); +// trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); +// trainTask.setResult(Face3dSeverHTTPConstant.result_fail); +// trainTask.setRequestResult("digital cloth 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); +// trainTaskMapper.updateById(trainTask); +// log.info("digital cloth 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); +// sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); +// sysHistory.setStatus(Face3dSeverHTTPConstant.result_fail); +// sysHistoryMapper.updateById(sysHistory); +// } +// } +// } +//} diff --git a/digital-application/src/main/java/digital/application/service/IMwTrainTaskService.java b/digital-application/src/main/java/digital/application/service/IMwTrainTaskService.java new file mode 100644 index 0000000..c69ab80 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/IMwTrainTaskService.java @@ -0,0 +1,43 @@ +package digital.application.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.dto.TrainTaskCallbackDTO; +import org.springframework.web.multipart.MultipartFile; +import digital.base.vo.Result; +import digital.bean.task.MwTrainTask; + +import java.util.List; +import java.util.concurrent.ExecutionException; + +/** + * @Description: mw_train_task + * @Author: jeecg-boot + * @Date: 2023-10-06 + * @Version: V1.0 + */ +public interface IMwTrainTaskService extends IService { + + /** + * 数字人服务 + * @return + * @param clothFileList + * @param modelFileList + */ + Result getFace3dSever(List clothFileList, List modelFileList, MultipartFile tileFile) ; + + + /** + * 换装体验任务 回调 + * @param trainTaskCallbackDTO + * @return + */ + Result trainTaskCallback(TrainTaskCallbackDTO trainTaskCallbackDTO); + + /** + * + * @return + */ + Result getCostTime(); + + +} diff --git a/digital-application/src/main/java/digital/application/service/ISysContactService.java b/digital-application/src/main/java/digital/application/service/ISysContactService.java new file mode 100644 index 0000000..8dff580 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/ISysContactService.java @@ -0,0 +1,18 @@ +package digital.application.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.dto.SubmitContactInfoDTO; +import digital.application.entity.SysContact; +import digital.base.vo.Result; + +/** + * @Description: sys_contact + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +public interface ISysContactService extends IService { + + Result submitContactInfo(SubmitContactInfoDTO submitContactInfoDTO); + +} diff --git a/digital-application/src/main/java/digital/application/service/ISysFileService.java b/digital-application/src/main/java/digital/application/service/ISysFileService.java new file mode 100644 index 0000000..99743e5 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/ISysFileService.java @@ -0,0 +1,151 @@ +package digital.application.service; + + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.dto.*; +import digital.application.dto.tjHair.GetHairDataDTO; +import digital.application.entity.SysFile; +import digital.base.vo.Result; +import digital.bean.task.DpUser; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +public interface ISysFileService extends IService { + + /** + * 衣服类型图片-分页列表查询 + * + * @param page + * @param clothType + * @return + */ + Result queryClothTypeList(Page page, String clothType); + + /** + * 上传图片分类 + * + * @return + */ + Result uploadCloth(UploadClothDTO uploadClothDTO); + + /** + * 衣服类型图片所有数据查询 + * + * @param clothType + * @return + */ + Result clothList(QueryClothTypeDTO clothType); + + Result uploadFileCloth(MultipartFile files); + + Result uploadModel(MultipartFile file, String sex) throws IOException; + + /** + * 获取模特列表 + * + * @return + */ + Result getModelList(GetModelDTO sex); + + /** + * 试穿 + * + * @param tryOnDTO + * @return + */ + Result tryOn(TryOnDTO tryOnDTO); + + /** + * @param callBackDTO + * @return + */ + Result callBack(CallBackDTO callBackDTO); + + /** + * 抓取图片 + * + * @param crawlerUrl + * @return + */ + Result grabPicture(String crawlerUrl); + + /** + * 加入衣橱 + * + * @param addWardrobeDTO + * @return + */ + Result addWardrobe(AddWardrobeDTO addWardrobeDTO); + + /** + * 取消加入 + * + * @param unJoinDTO + * @return + */ + Result unJoin(UnJoinDTO unJoinDTO); + + /** + * 查看试穿历史数据 + * + * @return + */ + Result getTryOnHistory(); + + + /** + * 查看写死手机号试穿的历史数据 + * + * @return + */ + Result getTargetTryOnHistory(DpUser dpUser); + + + /** + * 加入套装 + * + * @param addSuitDTO + * @return + */ + Result addSuit(AddSuitDTO addSuitDTO); + + /** + * @param file + * @return + */ + Result uploadAvatar(MultipartFile file); + + Result tryOnCallBack(TryOnCallBackDTO tryOnCallBackDTO); + + Result unTryOn(UnTryOnDTO unTryOnDTO); + + /** + * 批量删除历史数据 + * + * @param batchDelHistoryDTO + * @return + */ + Result batchDelHistory(BatchDelHistoryDTO batchDelHistoryDTO); + + /** + * 购买链接 + * + * @param buyLinksDTO + * @return + */ + Result buyLink(BuyLinksDTO buyLinksDTO); + + Result batchUploadClothFile(MultipartFile[] files); + + Result getHairData(GetHairDataDTO getHairData); + + Result swapHair(DpUser dpUser, String isHr, String clothIds, MultipartFile[] file, String sex); + + Result swapHairAsync(DpUser dpUser, String isHr, String clothIds, MultipartFile[] file, String modelUrls, String sex); + + Result getSwapHairHistory(DpUser dpUser); + + Result getSwapHairHistoryByTaskId(String taskId); +} diff --git a/digital-application/src/main/java/digital/application/service/SysHistoryService.java b/digital-application/src/main/java/digital/application/service/SysHistoryService.java new file mode 100644 index 0000000..7549066 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/SysHistoryService.java @@ -0,0 +1,8 @@ +package digital.application.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.entity.SysHistory; + +public interface SysHistoryService extends IService { + +} diff --git a/digital-application/src/main/java/digital/application/service/SysRoomService.java b/digital-application/src/main/java/digital/application/service/SysRoomService.java new file mode 100644 index 0000000..10f00ed --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/SysRoomService.java @@ -0,0 +1,64 @@ +package digital.application.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.dto.*; +import digital.application.entity.SysRoom; +import digital.base.vo.Result; + +public interface SysRoomService extends IService { + + /** + * 添加专题试衣间 + * + * @param addRoomDTO + * @return + */ + Result addRoom(AddRoomDTO addRoomDTO); + + /** + * 删除专题试衣间 + * + * @param delRoomDTO + * @return + */ + Result delRoom(DelRoomDTO delRoomDTO); + + /** + * 修改专题试衣间 + * + * @param updateRoomDTO + * @return + */ + Result updateRoom(UpdateRoomDTO updateRoomDTO); + + /** + * 查询本人专题试衣间 + * + * @return + */ + Result getRoomList(GetRoomListDTO getRoomListDTO); + + /** + * 专题试衣间-添加衣服 + * + * @param addRoomClothDTO + * @return + */ + Result addRoomCloth(AddRoomClothDTO addRoomClothDTO); + + /** + * 专题试衣间-查询对应试衣间列表 + * + * @return + */ + Result getRoomClothList(GetRoomClothListDTO getRoomClothListDTO); + + /** + * 专题试衣间-删除衣服 + * + * @param addRoomClothDTO + * @return + */ + Result delRoomCloth(AddRoomClothDTO addRoomClothDTO); + +} diff --git a/digital-application/src/main/java/digital/application/service/SysTaskQueueService.java b/digital-application/src/main/java/digital/application/service/SysTaskQueueService.java new file mode 100644 index 0000000..d7007f0 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/SysTaskQueueService.java @@ -0,0 +1,9 @@ +package digital.application.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.application.entity.SysTaskQueue; + +public interface SysTaskQueueService extends IService { + + +} diff --git a/digital-application/src/main/java/digital/application/service/impl/MwTrainTaskServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/MwTrainTaskServiceImpl.java new file mode 100644 index 0000000..4f138a8 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/MwTrainTaskServiceImpl.java @@ -0,0 +1,218 @@ +package digital.application.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.dto.TrainTaskCallbackDTO; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.service.IMwTrainTaskService; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.bean.task.MwTrainTask; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Service +@Slf4j +public class MwTrainTaskServiceImpl extends ServiceImpl implements IMwTrainTaskService { + + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Value("${cloth.uploaded_folder}") + private String uploaded_folder; + + + @Override + public Result getCostTime() { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(MwTrainTask::getUserId, loginUser.getId()); + queryWrapper.lambda().eq(MwTrainTask::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(MwTrainTask::getStatus, Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + queryWrapper.lambda().orderByDesc(MwTrainTask::getCreateTime); + queryWrapper.lambda().last("LIMIT 1"); + MwTrainTask mwTrainTask = trainTaskMapper.selectOne(queryWrapper); + if (mwTrainTask == null){ + return Result.ok(0); + } + Integer costTime = (mwTrainTask.getCostTime() != null) ? mwTrainTask.getCostTime() : 0; + return Result.ok(costTime); + } + + @Override + public Result getFace3dSever(List clothFileList, List modelFileList, MultipartFile tileFile) { +// String taskId = UUID.randomUUID().toString(); +// log.info("开始===执行任务!!!"+taskId); +// log.info("clothFileList " + clothFileList + " modelFileList=" + modelFileList + " tileFile=" + tileFile); +// if (CollectionUtil.isEmpty(clothFileList) || null == tileFile) { +// return Result.error("平铺图和服装图不能为空!", taskId); +// } +// MwTrainTask trainTask = new MwTrainTask(); +// trainTask.setTaskId(taskId); +// ////////////////////////////////////// 开始处理 clothFileList //////////////////////////////////////////////////////////////////// +// log.info("开始处理 clothFileList "); +// List clothPath = new ArrayList<>(); +// if (!CollectionUtil.isEmpty(clothFileList)) { +// for (MultipartFile file : clothFileList) { +// if (file != null) { +// log.info(taskId + " 上传 cloth ========================" + file.getOriginalFilename()); +// // 生成UUID文件名 +// String newFileName = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); +// log.info(taskId + " 上传 cloth 改名 ========================" + newFileName); +// try { +// String pathName = uploaded_folder + Face3dSeverHTTPConstant.UPLOADED_FOLDER_CLOTH + newFileName; +// Path path = Paths.get(pathName); +// // 检查文件路径是否存在 +// if (!Files.isDirectory(path)) { +// // 如果不存在,则创建路径中的目录 +// Files.createDirectories(path.getParent()); +// log.info("cloth 路径不存在,已创建。"); +// } else { +// log.info("cloth 路径已存在。"); +// } +// byte[] bytes = file.getBytes(); +// Files.write(path, bytes); +// clothPath.add(pathName); +// } catch (IOException e) { +// log.info(taskId + "cloth 落盘失败:", e); +// log.info(taskId + " 上传 cloth ========================" + String.format("图片落盘失败!{taskId: %s}", taskId)); +// } +// } +// } +// String commaSeparatedString = String.join(",", clothPath); +// trainTask.setClothPath(commaSeparatedString); +// } +// ////////////////////////////////////// 开始处理 modelFileList //////////////////////////////////////////////////////////////////// +// log.info(" 开始处理 clothFileList "); +// List modelPath = new ArrayList<>(); +// if (!CollectionUtil.isEmpty(modelFileList)) { +// for (MultipartFile file : modelFileList) { +// if (file != null) { +// log.info(taskId + " 上传 model ========================" + file.getOriginalFilename()); +// // 生成UUID文件名 +// String newFileName = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); +// log.info(taskId + " 上传 model 改名 ========================" + newFileName); +// try { +// String pathName = uploaded_folder + Face3dSeverHTTPConstant.UPLOADED_FOLDER_MODEL + newFileName; +// Path path = Paths.get(pathName); +// // 检查文件路径是否存在 +// if (!Files.isDirectory(path)) { +// // 如果不存在,则创建路径中的目录 +// Files.createDirectories(path.getParent()); +// log.info("model 路径不存在,已创建。"); +// } else { +// log.info("model 路径已存在。"); +// } +// byte[] bytes = file.getBytes(); +// Files.write(path, bytes); +// modelPath.add(pathName); +// } catch (IOException e) { +// log.info(taskId + "model 落盘失败:", e); +// log.info(taskId + " 上传 model 改名 ========================" + String.format(" model 落盘失败!{taskId: %s}", taskId)); +// } +// } +// } +// String modelPathString = String.join(",", modelPath); +// trainTask.setModelPath(modelPathString); +// } +// +// ////////////////////////////////////// 开始处理 平铺图 //////////////////////////////////////////////////////////////////// +// String tilePath = null; +// if (null != tileFile) { +// log.info(taskId + " 上传 平铺图 ========================" + tileFile.getOriginalFilename()); +// // 生成UUID文件名 +// String newFileName = UUID.randomUUID().toString() + tileFile.getOriginalFilename().substring(tileFile.getOriginalFilename().lastIndexOf(".")); +// log.info(taskId + " 上传 平铺图 改名 ========================" + newFileName); +// try { +// tilePath = uploaded_folder + Face3dSeverHTTPConstant.UPLOADED_FOLDER_TILE + newFileName; +// Path path = Paths.get(tilePath); +// // 检查文件路径是否存在 +// if (!Files.isDirectory(path)) { +// // 如果不存在,则创建路径中的目录 +// Files.createDirectories(path.getParent()); +// log.info("平铺图 路径不存在,已创建。"); +// } else { +// log.info("平铺图 路径已存在。"); +// } +// byte[] bytes = tileFile.getBytes(); +// Files.write(path, bytes); +// } catch (IOException e) { +// log.info(taskId + "平铺图 落盘失败:", e); +// log.info(taskId + " 上传 平铺图 改名 ========================" + String.format(" 平铺图 落盘失败!{taskId: %s}", taskId)); +// } +// } +// +// trainTask.setTilePath(tilePath); +// trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); +// trainTaskMapper.insert(trainTask); +// +// JSONObject clothParam = new JSONObject(); +// clothParam.put("taskId", taskId); +// clothParam.put("clothPathLists", clothPath); +// clothParam.put("modelPathLists", modelPath); +// clothParam.put("tilePath", tilePath); +// log.info("算法 clothParam =" + clothParam); +// +// try { +// ResponseEntity clothResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.DIGITAL_CLOTH, +// HttpMethod.POST, null, clothParam, JSONObject.class); +// String clothState = clothResult.getBody().get("status").toString(); +// log.info(taskId + " 返回结果信息成功 ==" + taskId + " status=" + clothState); +// if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { +// trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); +// trainTask.setResult(Face3dSeverHTTPConstant.result_fail); +// trainTask.setRequestResult(String.format("digital cloth 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); +// trainTaskMapper.updateById(trainTask); +// log.info(String.format("digital cloth 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); +// return Result.error(String.format("digital cloth 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); +// } +// // 尝试将返回结果转为JSON +// JSONObject jsonObject = clothResult.getBody(); +// log.info("data=" + jsonObject); +// return Result.ok("调用成功!!!"); +// } catch (Exception ex) { +// String message = ex.getMessage(); +// trainTask.setStatus(Face3dSeverHTTPConstant.result_fail); +// trainTask.setResult(Face3dSeverHTTPConstant.result_fail); +// trainTask.setRequestResult("digital cloth 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); +// trainTaskMapper.updateById(trainTask); +// log.info("digital cloth 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); +// return Result.error("digital cloth 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); +// } + return null; + } + + @Override + public Result trainTaskCallback(TrainTaskCallbackDTO trainTaskCallbackDTO) { + String taskId = trainTaskCallbackDTO.getTaskId(); + log.info("进入回调方法 " + taskId + " trainTaskCallbackDTO= " + trainTaskCallbackDTO); + if (oConvertUtils.isEmpty(taskId)) { + log.info("taskId 不能为空!!"); + return Result.error("taskId 不能为空!!"); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(MwTrainTask::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(MwTrainTask::getTaskId, taskId); + MwTrainTask mwTrainTask = trainTaskMapper.selectOne(queryWrapper); + if (null == mwTrainTask) { + log.info("数据库中无此任务信息!!"); + return Result.error("数据库中无此任务信息!!"); + } + mwTrainTask.setStatus(trainTaskCallbackDTO.getStatus()); + List urlList = trainTaskCallbackDTO.getUrlList(); + String resultString = String.join(",", urlList); + mwTrainTask.setResultImages(resultString); + trainTaskMapper.updateById(mwTrainTask); + log.info("回调成功!!"); + return Result.ok("回调成功!!"); + } + +} diff --git a/digital-application/src/main/java/digital/application/service/impl/SysContactServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/SysContactServiceImpl.java new file mode 100644 index 0000000..56a7cae --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/SysContactServiceImpl.java @@ -0,0 +1,37 @@ +package digital.application.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.dto.SubmitContactInfoDTO; +import digital.application.entity.SysContact; +import digital.application.mapper.SysContactMapper; +import digital.application.service.ISysContactService; +import digital.base.vo.Result; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.UUID; + +/** + * @Description: sys_contact + * @Author: jeecg-boot + * @Date: 2024-05-07 + * @Version: V1.0 + */ +@Service +public class SysContactServiceImpl extends ServiceImpl implements ISysContactService { + + @Autowired + private SysContactMapper sysContactMapper; + + @Override + public Result submitContactInfo(SubmitContactInfoDTO submitContactInfoDTO) { + String taskId = UUID.randomUUID().toString(); + SysContact sysContact = new SysContact(); + sysContact.setName(submitContactInfoDTO.getName()); + sysContact.setPhone(submitContactInfoDTO.getPhone()); + sysContact.setCompany(submitContactInfoDTO.getCompany()); + sysContact.setDescription(submitContactInfoDTO.getDescription()); + sysContactMapper.insert(sysContact); + return Result.OK("提交信息成功!", taskId); + } +} diff --git a/digital-application/src/main/java/digital/application/service/impl/SysFileServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/SysFileServiceImpl.java new file mode 100644 index 0000000..0b45207 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/SysFileServiceImpl.java @@ -0,0 +1,1955 @@ +package digital.application.service.impl; + +import cn.hutool.core.collection.CollectionUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.dto.*; +import digital.application.dto.tjHair.GetHairDataDTO; +import digital.application.entity.SysFile; +import digital.application.entity.SysHistory; +import digital.application.entity.SysTaskQueue; +import digital.application.mapper.MwTrainTaskMapper; +import digital.application.mapper.SysFileMapper; +import digital.application.mapper.SysHistoryMapper; +import digital.application.mapper.SysTaskQueueMapper; +import digital.application.service.ISysFileService; +import digital.application.service.SysHistoryService; +import digital.application.utils.AudioUtil; +import digital.application.utils.CommonUtils; +import digital.application.vo.*; +import digital.application.vo.tjHair.TjHairListVO; +import digital.base.constant.CommonConstant; +import digital.base.constant.Face3dSeverHTTPConstant; +import digital.base.constant.ZitaCommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.bean.task.DpUser; +import digital.bean.task.MwTrainTask; +import digital.config.oss.OssConfiguration; +import digital.system.jeecg.system.service.IDpUserService; +import digital.util.oss.OssBootUtil; +import digital.util.util.RestUtil; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.*; +import java.util.stream.Collectors; + +import static digital.application.utils.ImageUtils.uploadImagesInFolder; +import static digital.application.utils.TimeUtils.compareHour; +import static digital.base.constant.CommonConstant.TRY_ON_IN_PROCESS; +import java.net.URL; +import java.io.FileOutputStream; +import java.net.HttpURLConnection; + +@Slf4j +@Service +public class SysFileServiceImpl extends ServiceImpl implements ISysFileService { + + @Autowired + OssConfiguration ossConfiguration; + @Autowired + private MwTrainTaskMapper trainTaskMapper; + @Autowired + private SysFileMapper sysFileMapper; + @Value("${cloth.uploaded_folder}") + private String uploaded_folder; + @Autowired + private SysHistoryMapper sysHistoryMapper; + @Autowired + private IDpUserService dpUserService; + @Autowired + private SysTaskQueueMapper sysTaskQueueMapper; + @Autowired + private SysHistoryService sysHistoryService; + + @Override + public Result buyLink(BuyLinksDTO buyLinksDTO) { + String taskId = UUID.randomUUID().toString(); + String clothId = buyLinksDTO.getClothId(); + SysFile sysFile = sysFileMapper.selectById(clothId); + if (null == sysFile) { + return Result.error("此数据数据库不存在!", taskId); + } + sysFile.setBuyLink(buyLinksDTO.getBuyLink()); + sysFileMapper.updateById(sysFile); + return Result.OK("提交成功!"); + } + + @Override + public Result batchUploadClothFile(MultipartFile[] files) { + String taskId = UUID.randomUUID().toString(); + // 检查文件数量和大小 + if (files == null || files.length == 0) { + return Result.error("未选择任何文件!", taskId); + } + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + List uploadFileClothVOS = new ArrayList<>(); + for (MultipartFile file : files) { + SysFile sysFile = new SysFile(); + log.info(loginUser.getUsername() + " === " + taskId + " 上传 cloth ========================" + file.getOriginalFilename()); + String newFileName = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(loginUser.getUsername() + " === " + taskId + " 上传 cloth 改名 ========================" + newFileName); + try { + String pathName = uploaded_folder + "/cloth/" + newFileName; + Path path = Paths.get(pathName); + // 检查文件路径是否存在 + if (!Files.isDirectory(path)) { + // 如果不存在,则创建路径中的目录 + Files.createDirectories(path.getParent()); + log.info(loginUser.getUsername() + " === " + taskId + "cloth 路径不存在,已创建。"); + } else { + log.info(loginUser.getUsername() + " === " + taskId + "cloth 路径已存在。"); + } + // 使用输入流写入文件 + try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = Files.newOutputStream(path)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + // 生成UUID文件名 + sysFile.setExtendName(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))); + sysFile.setOssFileName(newFileName); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.CLOTH_FILE_TYPE); + sysFile.setFileName(file.getOriginalFilename()); + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), fileUrl); + sysFile.setFileUrl(savePath); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFile.setIsTemp("1"); + sysFile.setUserId(loginUser.getId()); + sysFile.setFilePath(pathName); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setFileUrl(savePath); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setThumbnailFileUrl(thumbnailURL); + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 列表信息==" + uploadFileClothVO); + uploadFileClothVOS.add(uploadFileClothVO); + } else { + log.error(loginUser.getUsername() + " === " + taskId + "添加上衣失败"); + } + } catch (IOException e) { + log.error(loginUser.getUsername() + " === " + taskId + "添加上衣失败异常!"); + } + } + return Result.OK(uploadFileClothVOS, taskId); + } + + @Override + public Result getHairData(GetHairDataDTO getHairData) { + String taskId = UUID.randomUUID().toString(); + String clothType = CommonConstant.HAIR_SWAP; + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getIsTemp, "0"); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getFileType, CommonConstant.HAIR_FILE_TYPE); + //可用状态 + queryWrapper.lambda().eq(SysFile::getFileStatus, CommonConstant.FILE_STATUS_ENABLE); + queryWrapper.lambda().eq(SysFile::getIsPerson, getHairData.getIsPerson()); + if (CommonConstant.COMMON_YES.equals(getHairData.getIsPerson())) { + //我的衣橱(个人) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(oConvertUtils.isNotEmpty(clothType), SysFile::getClothType, clothType) + .eq(SysFile::getUserId, getHairData.getUserId()))) + .or().like(oConvertUtils.isNotEmpty(clothType), SysFile::getCommonClothType, "in_" + clothType) + .like(oConvertUtils.isEmpty(clothType), SysFile::getCommonClothType, "in_")); + } else if (CommonConstant.COMMON_NO.equals(getHairData.getIsPerson())) { + //衣服库(公共,与个人无关) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(oConvertUtils.isNotEmpty(clothType), SysFile::getClothType, clothType) + .isNotNull(SysFile::getId))).or().like(oConvertUtils.isNotEmpty(clothType), SysFile::getCommonClothType, "in_" + clothType) + .like(oConvertUtils.isEmpty(clothType), SysFile::getCommonClothType, "in_")); + } + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + List sysFileListVO = new ArrayList<>(); //用户返回前端 + if (sysFileList != null && sysFileList.size() > 0) { + List filesToDelete = new ArrayList<>(); // 用于存储需要删除的文件ID + for (SysFile sysFile : sysFileList) { + Date createTime = sysFile.getCreateTime(); + boolean result = compareHour(createTime); + String fileStatus = sysFile.getFileStatus(); + if (("disable".equals(fileStatus) && result) || CommonConstant.FILE_STATUS_FAIL.equals(fileStatus)) { + filesToDelete.add(sysFile.getId()); + continue; + } + TjHairListVO queryClothTypeListVO = new TjHairListVO(); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setFileId(sysFile.getId()); + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + // 批量删除文件 + if (!filesToDelete.isEmpty()) { + sysFileMapper.deleteBatchIds(filesToDelete); + } + } + log.info(getHairData.getPhone() + " === " + taskId + "== 返回发型数据成功 =="); + return Result.OK(sysFileListVO, taskId); + } + + @Override + public Result swapHair(DpUser dpUser, String isHr, String clothIdsStr, MultipartFile[] files, String sex) { + String batchNo = UUID.randomUUID().toString(); + if (files == null || files.length == 0) { + return Result.error("请上传图片!"); + } + List modelIdList = new ArrayList<>(); + //上传模特图片 + for (MultipartFile file : files) { + log.info(dpUser.getAccount() + "==开始 上传模特头像==" + batchNo); + SysFile sysFile = new SysFile(); + log.info(dpUser.getAccount() + " === " + batchNo + " 上传 model ========================" + file.getOriginalFilename()); + // 生成UUID文件名 + String newFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(dpUser.getAccount() + " === " + batchNo + " 上传 model 改名 ========================" + newFileName); + try { + String pathName = uploaded_folder + "/modelPicture/" + newFileName; + Path path = Paths.get(pathName); + // 检查文件路径是否存在 + if (!Files.isDirectory(path)) { + // 如果不存在,则创建路径中的目录 + Files.createDirectories(path.getParent()); + log.info(dpUser.getAccount() + " === " + batchNo + "model 路径不存在,已创建。"); + } else { + log.info(dpUser.getAccount() + " === " + batchNo + "model 路径已存在。"); + } + // 使用输入流写入文件 + try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = Files.newOutputStream(path)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + sysFile.setExtendName(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))); + sysFile.setOssFileName(newFileName); + sysFile.setSex(sex); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.MODEL_FILE_TYPE); + sysFile.setFileName(file.getOriginalFilename()); + sysFile.setFilePath(pathName); + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), fileUrl); + sysFile.setFileUrl(savePath); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFile.setUserId(dpUser.getId()); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setFileUrl(savePath); + uploadFileClothVO.setThumbnailFileUrl(thumbnailURL); + log.info(dpUser.getAccount() + " === " + batchNo + "== 返回 上传模特头像=="); + modelIdList.add(sysFile.getId()); + } else { + log.info("上传model失败"); + return Result.error("上传model失败!", batchNo); + } + } catch (Exception e) { + log.info("上传model失败异常!"); + return Result.error("上传model失败异常!", batchNo); + } + } + TryOnDTO tryOns = new TryOnDTO(); + List tryOnDTOList = new ArrayList<>(); + //衣服id集合 + String[] split = clothIdsStr.split(","); + // 使用Arrays.asList方法将字符串数组转换为List + List clothIdList = Arrays.asList(split); + // 使用嵌套循环创建所有组合 + for (String modelId : modelIdList) { + for (String clothId : clothIdList) { + // 为每个组合创建一个新的列表 + tryOnDTOList.add(new TryOnDTO.TryOn(Collections.singletonList(clothId), modelId)); + } + } + tryOns.setTryOnList(tryOnDTOList); + tryOns.setIsHr(isHr); + String tryOnType; + if (1 == tryOnDTOList.size()) { + tryOnType = CommonConstant.TRY_ON_TYPE_SINGLE; + } else { + tryOnType = CommonConstant.TRY_ON_TYPE_BATCH; + } + String tryOnAlgo = CommonConstant.TRY_ON_TYPE_ALGO_HAIR; + //批量添加对应的数据 + List sysHistoryList = new ArrayList<>(); + for (int i = 0; i < tryOnDTOList.size(); i++) { + SysHistory sysHistory = new SysHistory(); + sysHistory.setFileUrl(TRY_ON_IN_PROCESS); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysHistory.setBatchNo(batchNo); + sysHistory.setTryOnType(tryOnType); + sysHistory.setTryOnAlgo(tryOnAlgo); + sysHistory.setUserId(dpUser.getId()); + sysHistory.setCreateTime(new Date()); + sysHistoryList.add(sysHistory); + } + sysHistoryService.saveBatch(sysHistoryList); + log.info("开始同步任务" + batchNo); + ////////////////// 开始处理换发型 ///////////////////// + if (CommonConstant.TRY_ON_TYPE_ALGO_HAIR.equals(tryOnAlgo)) { + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + return Result.error("数据库中无此数据! modelId=" + modelId, taskId); + } + List clothIds = tryOnDTO.getClothIds(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setTryOnAlgo(tryOnAlgo); + trainTask.setUserId(dpUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(String.join(",", clothIds)); + trainTask.setModelPath(modelImage.getFilePath()); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + log.info("sysHistory===" + sysHistory); + //添加完毕 + JSONObject clothParam = new JSONObject(); + for (String clothId : clothIds) { + SysFile clothImage = sysFileMapper.selectWithoutLogicDeleteById(clothId); + if (null == clothImage) { + continue; + } + clothParam.put("hair_id", CommonUtils.checkAndReplaceLastSegment(clothImage.getMaterialPath(), clothId)); + clothParam.put("hair_material_dir", clothImage.getMaterialPath()); + } + clothParam.put("task_id", taskId); + clothParam.put("is_hr", tryOns.getIsHr()); + clothParam.put("user_img_path", modelImage.getFilePath()); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setTryOnAlgo(tryOnAlgo); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(dpUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueue.setIsHr(tryOns.getIsHr()); + sysTaskQueueMapper.insert(sysTaskQueue); + log.info("提交成功!sysTaskQueue==" + sysTaskQueue); + } + } + return Result.ok("提交成功!", batchNo); + } + + + public static String getFileNameFromURL(String urlString) { + try { + URL url = new URL(urlString); + // 使用URI和Paths来获取文件名 + String fileName = url.getFile(); + fileName = fileName.substring(fileName.lastIndexOf("/") + 1); // 获取文件名 + return fileName; + } catch (Exception e) { + e.printStackTrace(); + return null; // 或者抛出一个自定义的异常 + } + } + + public static void downloadImage(String imageUrl, String outputFilePath) { + try { + URL url = new URL(imageUrl); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + + // 检查响应码 + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + // 获取输入流 + try (InputStream inputStream = connection.getInputStream(); + FileOutputStream outputStream = new FileOutputStream(outputFilePath)) { + + byte[] buffer = new byte[4096]; + int bytesRead; + // 将输入流写入到本地文件 + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + + System.out.println("Downloaded: " + outputFilePath); + } else { + System.out.println("Failed to download: " + imageUrl + " (Response code: " + responseCode + ")"); + } + + // 断开连接 + connection.disconnect(); + + } catch (IOException e) { + e.printStackTrace(); + System.out.println("Error downloading: " + imageUrl); + } + } + + @Override + public Result swapHairAsync(DpUser dpUser, String isHr, String clothIdsStr, MultipartFile[] files, String modelUrls, String sex) { + String batchNo = UUID.randomUUID().toString(); +// if (files == null || files.length == 0) { +// return Result.error("请上传图片!"); +// } + List modelIdList = new ArrayList<>(); + + List modelUrlLists =Arrays.asList(modelUrls.split(",")); + + // 判断 modelUrls 是否为空 + if (!modelUrls.isEmpty()) { + for (String modelUrl : modelUrlLists) { + // 从 url 中获取文件名 + String modelImgName = getFileNameFromURL(modelUrl); + // 下载文件 本地存储文件 + String pathName = uploaded_folder + "/modelPicture/" + modelImgName; + downloadImage(modelUrl, pathName); + SysFile sysFile = new SysFile(); + sysFile.setExtendName(modelImgName.substring(modelImgName.lastIndexOf("."))); + sysFile.setOssFileName(modelImgName); + sysFile.setSex(sex); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.MODEL_FILE_TYPE); + sysFile.setFileName(modelImgName); + sysFile.setFilePath(pathName); + sysFile.setFileUrl(modelUrl); + sysFile.setThumbnailFileUrl(modelUrl); + sysFile.setUserId(dpUser.getId()); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setFileUrl(modelUrl); + uploadFileClothVO.setThumbnailFileUrl(modelUrl); + log.info(dpUser.getAccount() + " === " + batchNo + "== 返回 上传模特头像=="); + modelIdList.add(sysFile.getId()); + + } + + } else { + // 使用文件流 + //上传模特图片 + for (MultipartFile file : files) { + log.info(dpUser.getAccount() + "==开始 上传模特头像==" + batchNo); + SysFile sysFile = new SysFile(); + log.info(dpUser.getAccount() + " === " + batchNo + " 上传 model ========================" + file.getOriginalFilename()); + // 生成UUID文件名 + String newFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(dpUser.getAccount() + " === " + batchNo + " 上传 model 改名 ========================" + newFileName); + try { + String pathName = uploaded_folder + "/modelPicture/" + newFileName; + Path path = Paths.get(pathName); + // 检查文件路径是否存在 + if (!Files.isDirectory(path)) { + // 如果不存在,则创建路径中的目录 + Files.createDirectories(path.getParent()); + log.info(dpUser.getAccount() + " === " + batchNo + "model 路径不存在,已创建。"); + } else { + log.info(dpUser.getAccount() + " === " + batchNo + "model 路径已存在。"); + } + // 使用输入流写入文件 + try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = Files.newOutputStream(path)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + sysFile.setExtendName(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))); + sysFile.setOssFileName(newFileName); + sysFile.setSex(sex); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.MODEL_FILE_TYPE); + sysFile.setFileName(file.getOriginalFilename()); + sysFile.setFilePath(pathName); + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), fileUrl); + sysFile.setFileUrl(savePath); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFile.setUserId(dpUser.getId()); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setFileUrl(savePath); + uploadFileClothVO.setThumbnailFileUrl(thumbnailURL); + log.info(dpUser.getAccount() + " === " + batchNo + "== 返回 上传模特头像=="); + modelIdList.add(sysFile.getId()); + } else { + log.info("上传model失败"); + return Result.error("上传model失败!", batchNo); + } + } catch (Exception e) { + log.info("上传model失败异常!"); + return Result.error("上传model失败异常!", batchNo); + } + } + } + + + TryOnDTO tryOns = new TryOnDTO(); + List tryOnDTOList = new ArrayList<>(); + //衣服id集合 + String[] split = clothIdsStr.split(","); + // 使用Arrays.asList方法将字符串数组转换为List + List clothIdList = Arrays.asList(split); + // 使用嵌套循环创建所有组合 + for (String modelId : modelIdList) { + for (String clothId : clothIdList) { + // 为每个组合创建一个新的列表 + tryOnDTOList.add(new TryOnDTO.TryOn(Collections.singletonList(clothId), modelId)); + } + } + tryOns.setTryOnList(tryOnDTOList); + tryOns.setIsHr(isHr); + String tryOnType; + if (1 == tryOnDTOList.size()) { + tryOnType = CommonConstant.TRY_ON_TYPE_SINGLE; + } else { + tryOnType = CommonConstant.TRY_ON_TYPE_BATCH; + } + String tryOnAlgo = CommonConstant.TRY_ON_TYPE_ALGO_HAIR; + //批量添加对应的数据 + List sysHistoryList = new ArrayList<>(); + for (int i = 0; i < tryOnDTOList.size(); i++) { + SysHistory sysHistory = new SysHistory(); + sysHistory.setFileUrl(TRY_ON_IN_PROCESS); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysHistory.setBatchNo(batchNo); + sysHistory.setTryOnType(tryOnType); + sysHistory.setTryOnAlgo(tryOnAlgo); + sysHistory.setUserId(dpUser.getId()); + sysHistory.setCreateBy(dpUser.getAccount()); + sysHistory.setUpdateBy(dpUser.getAccount()); + sysHistory.setCreateTime(new Date()); + sysHistoryList.add(sysHistory); + } + sysHistoryService.saveBatch(sysHistoryList); + log.info("开始同步任务" + batchNo); + ////////////////// 开始处理换发型 ///////////////////// + if (CommonConstant.TRY_ON_TYPE_ALGO_HAIR.equals(tryOnAlgo)) { + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + return Result.error("数据库中无此数据! modelId=" + modelId, taskId); + } + List clothIds = tryOnDTO.getClothIds(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setTryOnAlgo(tryOnAlgo); + trainTask.setUserId(dpUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(String.join(",", clothIds)); + trainTask.setModelPath(modelImage.getFilePath()); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + log.info("sysHistory===" + sysHistory); + //添加完毕 + JSONObject clothParam = new JSONObject(); + for (String clothId : clothIds) { + SysFile clothImage = sysFileMapper.selectWithoutLogicDeleteById(clothId); + if (null == clothImage) { + continue; + } + clothParam.put("hair_id", CommonUtils.checkAndReplaceLastSegment(clothImage.getMaterialPath(), clothId)); + clothParam.put("hair_material_dir", clothImage.getMaterialPath()); + } + clothParam.put("task_id", taskId); + clothParam.put("is_hr", tryOns.getIsHr()); + clothParam.put("user_img_path", modelImage.getFilePath()); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setTryOnAlgo(tryOnAlgo); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(dpUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueue.setIsHr(tryOns.getIsHr()); + sysTaskQueueMapper.insert(sysTaskQueue); + log.info("提交成功!sysTaskQueue==" + sysTaskQueue); + } + } + return Result.ok("提交成功!", batchNo); + } + + + @Override + public Result getSwapHairHistory(DpUser dpUser) { + String taskId = UUID.randomUUID().toString(); + List userHistoryMaps = sysHistoryMapper.getUserHistory(dpUser.getId()); + List tryOnHistoryVOS = new ArrayList<>(); + for (UserHistoryMap userHistoryMap : userHistoryMaps) { + GetTryOnHistoryVO getTryOnHistoryVO = new GetTryOnHistoryVO(); + getTryOnHistoryVO.setCreateTime(userHistoryMap.getCreateTime()); + String historyIdFileUrls = userHistoryMap.getHistoryIdFileUrls(); + // 使用逗号分割字符串,并将结果存储在List中 + List clothVOlist = new ArrayList<>(Arrays.asList(historyIdFileUrls.split(","))); + // 输出结果 + List clothList = new ArrayList<>(); + for (String historyIdFileUrl : clothVOlist) { + int hashIndex = historyIdFileUrl.indexOf('#'); + if (hashIndex != -1) { + String part1 = historyIdFileUrl.substring(0, hashIndex); + String part2 = historyIdFileUrl.substring(hashIndex + 1); + GetTryOnHistoryVO.ClothVO clothVO = new GetTryOnHistoryVO.ClothVO(); + clothVO.setHistoryId(part1); + clothVO.setUrl(part2); + clothVO.setTaskId(userHistoryMap.getBatchNo()); + clothList.add(clothVO); + } + } + getTryOnHistoryVO.setClothList(clothList); + tryOnHistoryVOS.add(getTryOnHistoryVO); + } + List sortedTryOnHistoryVOS = tryOnHistoryVOS.stream().sorted(Comparator.comparing(GetTryOnHistoryVO::getCreateTime).reversed()).collect(Collectors.toList()); + return Result.ok(sortedTryOnHistoryVOS, taskId); + } + + @Override + public Result getSwapHairHistoryByTaskId(String taskId) { + List sortedSwapHairHistory = new ArrayList<>(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysHistory::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysHistory::getBatchNo, taskId); + List sysHistoryList = sysHistoryMapper.selectList(queryWrapper); + for (SysHistory sysHistory : sysHistoryList) { + GetSwapHairHistoryVO getSwapHairHistoryVO = new GetSwapHairHistoryVO(); + getSwapHairHistoryVO.setHistoryId(sysHistory.getId()); + getSwapHairHistoryVO.setUrl(sysHistory.getFileUrl()); + getSwapHairHistoryVO.setTaskId(sysHistory.getBatchNo()); + getSwapHairHistoryVO.setCreateTime(sysHistory.getCreateTime()); + sortedSwapHairHistory.add(getSwapHairHistoryVO); + } + return Result.ok(sortedSwapHairHistory, taskId); + } + + @Override + public Result uploadFileCloth(MultipartFile file) { + String taskId = UUID.randomUUID().toString(); + if (null == file) { + return Result.error("上传文件不能为空!", taskId); + } + SysFile sysFile = new SysFile(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info(loginUser.getUsername() + "==开始 添加上衣==" + taskId); + log.info(loginUser.getUsername() + " === " + taskId + " 上传 cloth ========================" + file.getOriginalFilename()); + String newFileName = UUID.randomUUID().toString() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(loginUser.getUsername() + " === " + taskId + " 上传 cloth 改名 ========================" + newFileName); + try { + String pathName = uploaded_folder + "/cloth/" + newFileName; + Path path = Paths.get(pathName); + // 检查文件路径是否存在 + if (!Files.isDirectory(path)) { + // 如果不存在,则创建路径中的目录 + Files.createDirectories(path.getParent()); + log.info(loginUser.getUsername() + " === " + taskId + "cloth 路径不存在,已创建。"); + } else { + log.info(loginUser.getUsername() + " === " + taskId + "cloth 路径已存在。"); + } + // 使用输入流写入文件 + try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = Files.newOutputStream(path)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } + // 生成UUID文件名 + sysFile.setExtendName(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))); + sysFile.setOssFileName(newFileName); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.CLOTH_FILE_TYPE); + sysFile.setFileName(file.getOriginalFilename()); + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), fileUrl); + sysFile.setFileUrl(savePath); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFile.setIsTemp("1"); + sysFile.setUserId(loginUser.getId()); + sysFile.setFilePath(pathName); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setFileUrl(savePath); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setThumbnailFileUrl(thumbnailURL); + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 列表信息==" + uploadFileClothVO); + return Result.OK(uploadFileClothVO, taskId); + } else { + log.info(loginUser.getUsername() + " === " + taskId + "添加上衣失败"); + return Result.error("添加上衣失败!", taskId); + } + } catch (IOException e) { + log.info(loginUser.getUsername() + " === " + taskId + "添加上衣失败异常!"); + return Result.error("添加上衣失败异常!", taskId); + } + } + + + @Override + public Result unTryOn(UnTryOnDTO unTryOnDTO) { + String taskId = UUID.randomUUID().toString(); + List historyIdList = unTryOnDTO.getHistoryIds(); + if (historyIdList != null && historyIdList.size() > 0) { + for (String historyId : historyIdList) { + SysHistory sysHistory = sysHistoryMapper.selectById(historyId); + if (sysHistory != null) { + String tryTaskId = sysHistory.getTaskId(); + SysTaskQueue sysTaskQueue = sysTaskQueueMapper.selectOne(new QueryWrapper().lambda().eq(SysTaskQueue::getTaskId, tryTaskId)); + + if (sysTaskQueue != null) { + if (Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT.equals(sysTaskQueue.getStatus())) { + //草稿状态可以取消 + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_CANCEL); + sysTaskQueueMapper.updateById(sysTaskQueue); + //删除生成记录 + sysHistoryMapper.deleteById(historyId); + //查询训练表 + MwTrainTask mwTrainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, tryTaskId)); + if (mwTrainTask != null) { + mwTrainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_CANCEL); + trainTaskMapper.updateById(mwTrainTask); + } + } + } + } + } + } + return Result.OK("取消成功!", taskId); + } + + @Override + public Result batchDelHistory(BatchDelHistoryDTO batchDelHistoryDTO) { + sysHistoryService.removeBatchByIds(batchDelHistoryDTO.getHistoryIds()); + return Result.OK("删除成功!"); + } + + @Override + public Result tryOnCallBack(TryOnCallBackDTO tryOnCallBackDTO) { + log.info("换装回调方法 ==" + tryOnCallBackDTO.toString()); + String filePath = tryOnCallBackDTO.getFilePath(); + SysHistory sysHistory = sysHistoryMapper.selectOne(new QueryWrapper().lambda().eq(SysHistory::getTaskId, tryOnCallBackDTO.getTaskId())); + MwTrainTask mwTrainTask = trainTaskMapper.selectOne(new QueryWrapper().lambda().eq(MwTrainTask::getTaskId, sysHistory.getTaskId())); + if (CommonConstant.CALLBACK_SUCCESS.equals(tryOnCallBackDTO.getStatus())) { + log.info("换装 成功!"); + if (null != sysHistory) { + File file = new File(filePath); + // 生成UUID文件名 + String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); + String filepath = OssBootUtil.uploadOssVideo(file, CommonConstant.PUTON_SWAP, newFileName); + String fileUrl = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), filepath, null); + sysHistory.setFileUrl(fileUrl); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + sysHistoryMapper.updateById(sysHistory); + // 更新任务 + if (null != mwTrainTask) { + mwTrainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_SUCCESS); + mwTrainTask.setRequestResult(tryOnCallBackDTO.getMsg()); + trainTaskMapper.updateById(mwTrainTask); + } + } + } else { + //换装失败 + log.info("换装 失败!"); + if (null != sysHistory) { + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_FAIL); + sysHistory.setFileUrl(CommonConstant.TRY_ON_FAIL); + sysHistoryMapper.updateById(sysHistory); + } + // 更新任务 + if (null != mwTrainTask) { + mwTrainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_FAIL); + mwTrainTask.setResult(Face3dSeverHTTPConstant.result_fail); + mwTrainTask.setRequestResult("digital cloth 任务失败!" + tryOnCallBackDTO.getMsg()); + trainTaskMapper.updateById(mwTrainTask); + } + } + return Result.OK("回调执行成功!"); + } + + @Override + public Result uploadAvatar(MultipartFile file) { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + DpUser user = dpUserService.getOne(new QueryWrapper().lambda().eq(DpUser::getAccount, loginUser.getUsername())); + if (null == user) { + return Result.error("数据库中无此用户!"); + } + log.info(loginUser.getUsername() + "==开始 上传头像==" + taskId); + log.info(loginUser.getUsername() + " === " + taskId + " 上传 头像 ========================" + file.getOriginalFilename()); + // 生成UUID文件名 + String newFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(loginUser.getUsername() + " === " + taskId + " 上传 头像 改名 ========================" + newFileName); + try { + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + user.setAvatar(savePath); + dpUserService.updateById(user); + log.info(loginUser.getUsername() + " === " + taskId + " 上传 头像 成功 ========================"); + return Result.OK("上传成功!", taskId); + } else { + log.info("上传头像失败"); + return Result.error("上传头像失败!", taskId); + } + } catch (Exception e) { + log.info("上传model失败异常!"); + return Result.error("上传model失败异常!", taskId); + } + } + + @Override + public Result addSuit(AddSuitDTO addSuitDTO) { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String topClothId = addSuitDTO.getTopClothId(); + String bottomClothId = addSuitDTO.getBottomClothId(); + SysFile topCloth = sysFileMapper.selectById(topClothId); + SysFile bottomCloth = sysFileMapper.selectById(bottomClothId); + if (topCloth == null || bottomCloth == null) { + return Result.error("数据库中无此数据!"); + } + SysFile sysFile = new SysFile(); + BeanUtils.copyProperties(topCloth, sysFile); + sysFile.setId(null); + sysFile.setCommonClothType(null); + sysFile.setCreateTime(null); + sysFile.setUpdateTime(null); + sysFile.setClothType("suit"); + sysFile.setUserId(loginUser.getId()); + JSONArray imageArray = new JSONArray(); + + JSONArray thumbnailImageArray = new JSONArray(); + + // 创建一个JSONObject来存储第一张图片的信息,并添加到JSONArray中 + JSONObject imageObj1 = new JSONObject(); + imageObj1.put("clothId", topClothId); + imageObj1.put("clothType", "topCloth"); + imageObj1.put("fileUrl", topCloth.getFileUrl()); + imageArray.add(imageObj1); + + JSONObject imageObj11 = new JSONObject(); + imageObj11.put("clothId", topClothId); + imageObj11.put("clothType", "topCloth"); + imageObj11.put("thumbnailFileUrl", topCloth.getThumbnailFileUrl()); + thumbnailImageArray.add(imageObj11); + + // 创建一个JSONObject来存储第二张图片的信息,并添加到JSONArray中 + JSONObject imageObj2 = new JSONObject(); + imageObj2.put("clothId", bottomClothId); + imageObj2.put("clothType", "bottomCloth"); + imageObj2.put("fileUrl", bottomCloth.getFileUrl()); + imageArray.add(imageObj2); + + JSONObject imageObj22 = new JSONObject(); + imageObj22.put("clothId", bottomClothId); + imageObj22.put("clothType", "bottomCloth"); + imageObj22.put("thumbnailFileUrl", bottomCloth.getThumbnailFileUrl()); + thumbnailImageArray.add(imageObj22); + + // 将JSONArray转换为JSON字符串 + sysFile.setFileUrl(imageArray.toJSONString()); + sysFile.setThumbnailFileUrl(thumbnailImageArray.toJSONString()); + sysFile.setIsPerson(CommonConstant.COMMON_YES); + sysFileMapper.insert(sysFile); + return Result.ok("加入成功!", taskId); + } + + @Override + public Result uploadModel(MultipartFile file, String sex) throws IOException { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info(loginUser.getUsername() + "==开始 上传模特头像==" + taskId); + SysFile sysFile = new SysFile(); + log.info(loginUser.getUsername() + " === " + taskId + " 上传 model ========================" + file.getOriginalFilename()); + // 生成UUID文件名 + String newFileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); + ////////////////////////////////////写入文件夹//////////////////////////////////////////////////// + log.info(loginUser.getUsername() + " === " + taskId + " 上传 model 改名 ========================" + newFileName); + try { + String pathName = uploaded_folder + "/modelPicture/" + newFileName; + Path path = Paths.get(pathName); + // 检查文件路径是否存在 + if (!Files.isDirectory(path)) { + // 如果不存在,则创建路径中的目录 + Files.createDirectories(path.getParent()); + log.info(loginUser.getUsername() + " === " + taskId + "model 路径不存在,已创建。"); + } else { + log.info(loginUser.getUsername() + " === " + taskId + "model 路径已存在。"); + } + // 使用输入流写入文件 + try (InputStream inputStream = file.getInputStream(); OutputStream outputStream = Files.newOutputStream(path)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + sysFile.setExtendName(file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))); + sysFile.setOssFileName(newFileName); + sysFile.setSex(sex); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFileType(CommonConstant.MODEL_FILE_TYPE); + sysFile.setFileName(file.getOriginalFilename()); + sysFile.setFilePath(pathName); + String fileUrl = OssBootUtil.uploadOssMat(file, CommonConstant.DIGITAL_CLOTH, ossConfiguration.getBucketName(), newFileName); + if (fileUrl != null) { + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), fileUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), fileUrl); + sysFile.setFileUrl(savePath); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFile.setUserId(loginUser.getId()); + sysFileMapper.insert(sysFile); + UploadFileClothVO uploadFileClothVO = new UploadFileClothVO(); + uploadFileClothVO.setId(sysFile.getId()); + uploadFileClothVO.setFileUrl(savePath); + uploadFileClothVO.setThumbnailFileUrl(thumbnailURL); + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 上传模特头像=="); + return Result.OK(uploadFileClothVO, taskId); + } else { + log.info("上传model失败"); + return Result.error("上传model失败!", taskId); + } + } catch (Exception e) { + log.info("上传model失败异常!"); + return Result.error("上传model失败异常!", taskId); + } + } + + + @Override + public Result getTryOnHistory() { + String taskId = UUID.randomUUID().toString(); +// log.info(taskId + " 开始查询历史数据 "); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + Integer inProcessCount = 0; + + List userHistoryMaps = new ArrayList<>(); + if (CommonConstant.ROLE_TYPE_SUPER_ADMIN.equals(loginUser.getRoleType())) { + userHistoryMaps = sysHistoryMapper.getAllUserHistory(); + } else { + userHistoryMaps = sysHistoryMapper.getUserHistory(loginUser.getId()); + } + List tryOnHistoryVOS = new ArrayList<>(); + for (UserHistoryMap userHistoryMap : userHistoryMaps) { + GetTryOnHistoryVO getTryOnHistoryVO = new GetTryOnHistoryVO(); + getTryOnHistoryVO.setCreateTime(userHistoryMap.getCreateTime()); + String historyIdFileUrls = userHistoryMap.getHistoryIdFileUrls(); + // 使用逗号分割字符串,并将结果存储在List中 + List clothVOlist = new ArrayList<>(Arrays.asList(historyIdFileUrls.split(","))); + // 输出结果 + List clothList = new ArrayList<>(); + for (String historyIdFileUrl : clothVOlist) { + int hashIndex = historyIdFileUrl.indexOf('#'); + if (hashIndex != -1) { + String part1 = historyIdFileUrl.substring(0, hashIndex); + String part2 = historyIdFileUrl.substring(hashIndex + 1); + + // 判断是否在进行中 + if (part2.equals(TRY_ON_IN_PROCESS)) { + inProcessCount += 1; + } + + GetTryOnHistoryVO.ClothVO clothVO = new GetTryOnHistoryVO.ClothVO(); + clothVO.setHistoryId(part1); + clothVO.setUrl(part2); + clothList.add(clothVO); + } + } + getTryOnHistoryVO.setClothList(clothList); + tryOnHistoryVOS.add(getTryOnHistoryVO); + } + List sortedTryOnHistoryVOS = tryOnHistoryVOS.stream().sorted(Comparator.comparing(GetTryOnHistoryVO::getCreateTime).reversed()).collect(Collectors.toList()); + return Result.ok(sortedTryOnHistoryVOS, taskId, inProcessCount); + } + + @Override + public Result getTargetTryOnHistory(DpUser dpUser) { + String taskId = UUID.randomUUID().toString(); +// log.info(taskId + " 开始查询历史数据 "); + Integer inProcessCount = 0; + + List userHistoryMaps = new ArrayList<>(); + + userHistoryMaps = sysHistoryMapper.getUserHistory(dpUser.getId()); + + List tryOnHistoryVOS = new ArrayList<>(); + for (UserHistoryMap userHistoryMap : userHistoryMaps) { + GetTryOnHistoryVO getTryOnHistoryVO = new GetTryOnHistoryVO(); + getTryOnHistoryVO.setCreateTime(userHistoryMap.getCreateTime()); + String historyIdFileUrls = userHistoryMap.getHistoryIdFileUrls(); + // 使用逗号分割字符串,并将结果存储在List中 + List clothVOlist = new ArrayList<>(Arrays.asList(historyIdFileUrls.split(","))); + // 输出结果 + List clothList = new ArrayList<>(); + for (String historyIdFileUrl : clothVOlist) { + int hashIndex = historyIdFileUrl.indexOf('#'); + if (hashIndex != -1) { + String part1 = historyIdFileUrl.substring(0, hashIndex); + String part2 = historyIdFileUrl.substring(hashIndex + 1); + + // 判断是否在进行中 + if (part2.equals(TRY_ON_IN_PROCESS)) { + inProcessCount += 1; + } + + GetTryOnHistoryVO.ClothVO clothVO = new GetTryOnHistoryVO.ClothVO(); + clothVO.setHistoryId(part1); + clothVO.setUrl(part2); + clothList.add(clothVO); + } + } + getTryOnHistoryVO.setClothList(clothList); + tryOnHistoryVOS.add(getTryOnHistoryVO); + } + List sortedTryOnHistoryVOS = tryOnHistoryVOS.stream().sorted(Comparator.comparing(GetTryOnHistoryVO::getCreateTime).reversed()).collect(Collectors.toList()); + return Result.ok(sortedTryOnHistoryVOS, taskId, inProcessCount); + } + + + @Override + public Result unJoin(UnJoinDTO unJoinDTO) { + String taskId = UUID.randomUUID().toString(); + String clothId = unJoinDTO.getClothId(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getWardrobeId, clothId); + queryWrapper.lambda().eq(SysFile::getUserId, loginUser.getId()); + queryWrapper.lambda().eq(SysFile::getIsPerson, CommonConstant.COMMON_YES); + List sysFileList = sysFileMapper.selectList(queryWrapper); + if (sysFileList == null || sysFileList.isEmpty()) { + return Result.error("数据不存在!", taskId); + } + sysFileMapper.deleteBatchIds(sysFileList); + return Result.OK("操作成功!", taskId); + } + + + @Override + public Result addWardrobe(AddWardrobeDTO addWardrobeDTO) { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String clothId = addWardrobeDTO.getClothId(); + SysFile s = sysFileMapper.selectById(clothId); + if (s == null) { + return Result.error("数据不存在!", taskId); + } + Long count = sysFileMapper.selectCount(new QueryWrapper().lambda().eq(SysFile::getWardrobeId, clothId).eq(SysFile::getUserId, loginUser.getId())); + if (count > 0) { + return Result.OK("请勿重复添加"); + } + s.setWardrobeId(clothId); + s.setId(null); + s.setUserId(loginUser.getId()); + s.setIsPerson(CommonConstant.COMMON_YES); + sysFileMapper.insert(s); + return Result.OK("添加成功!", taskId); + } + + + @Override + public Result clothList(QueryClothTypeDTO queryClothTypeDTO) { + String clothType = queryClothTypeDTO.getClothType(); + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info(loginUser.getUsername() + " === " + taskId + "开始 衣服类型图片"); + ///////////////////////////// 开始 换内衣 /////////////////////////////////////// + if (CommonConstant.TYPE_UNDERWEAR.equals(clothType)) { + List sysFileListVO = new ArrayList<>(); //用户返回前端 + if (ZitaCommonConstant.sex_male.equals(queryClothTypeDTO.getSex())) { + //性别男返回空 + return Result.OK(sysFileListVO, taskId); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getIsTemp, "0"); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getClothType, CommonConstant.TYPE_UNDERWEAR); + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + if (sysFileList != null && sysFileList.size() > 0) { + List wardrobeIdList = sysFileMapper.selectObjs(new QueryWrapper().lambda() + .eq(SysFile::getUserId, loginUser.getId()).select(SysFile::getWardrobeId)); + // 将List转换为Set,自动去除重复项 + Set wardrobeIdSet = new HashSet<>(wardrobeIdList); + for (SysFile sysFile : sysFileList) { + QueryClothTypeListVO queryClothTypeListVO = new QueryClothTypeListVO(); + queryClothTypeListVO.setFileStatus(sysFile.getFileStatus()); + queryClothTypeListVO.setClothType(sysFile.getClothType()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setBuyLink(sysFile.getBuyLink()); + queryClothTypeListVO.setClothId(sysFile.getId()); + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + if (wardrobeIdSet.contains(sysFile.getId())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_NO); + } + } + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + } + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 内置身材图片 =="); + return Result.OK(sysFileListVO, taskId); + } + + ///////////////////////////// 结束 换内衣 /////////////////////////////////////// + + ///////////////////////////// 开始 换身材 /////////////////////////////////////// + if (CommonConstant.TYPE_FIGURE.equals(clothType)) { + List sysFileListVO = new ArrayList<>(); //用户返回前端 + if (ZitaCommonConstant.sex_female.equals(queryClothTypeDTO.getSex())) { + //性别女返回空 + return Result.OK(sysFileListVO, taskId); + } + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getIsTemp, "0"); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getClothType, CommonConstant.TYPE_FIGURE); + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + if (sysFileList != null && sysFileList.size() > 0) { + List wardrobeIdList = sysFileMapper.selectObjs(new QueryWrapper().lambda().eq(SysFile::getUserId, loginUser.getId()).select(SysFile::getWardrobeId)); + // 将List转换为Set,自动去除重复项 + Set wardrobeIdSet = new HashSet<>(wardrobeIdList); + for (SysFile sysFile : sysFileList) { + QueryClothTypeListVO queryClothTypeListVO = new QueryClothTypeListVO(); + queryClothTypeListVO.setFileStatus(sysFile.getFileStatus()); + queryClothTypeListVO.setClothType(sysFile.getClothType()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setBuyLink(sysFile.getBuyLink()); + queryClothTypeListVO.setClothId(sysFile.getId()); + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + if (wardrobeIdSet.contains(sysFile.getId())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_NO); + } + } + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + } + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 内置身材图片 =="); + return Result.OK(sysFileListVO, taskId); + } + + ///////////////////////////// 结束 换身材 /////////////////////////////////////// + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getIsTemp, "0"); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + if (CommonConstant.TRY_ON_TYPE_ALGO_HAIR.equals(clothType)) { + queryWrapper.lambda().eq(SysFile::getFileType, CommonConstant.HAIR_FILE_TYPE); + } else { + queryWrapper.lambda().eq(SysFile::getFileType, CommonConstant.CLOTH_FILE_TYPE); + } + queryWrapper.lambda().eq(SysFile::getIsPerson, queryClothTypeDTO.getIsPerson()); + if (!CommonConstant.TRY_ON_TYPE_ALGO_HAIR.equals(clothType)) { //发型不区分男女 + queryWrapper.lambda().eq(SysFile::getSex, queryClothTypeDTO.getSex()); + } + if (CommonConstant.EXCLUDE_SUIT.equals(queryClothTypeDTO.getClothType())) { + //查询除了套装的衣服数据 + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + //我的衣橱(个人) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(SysFile::getClothType, CommonConstant.TYPE_TOP_CLOTH) + .or().eq(SysFile::getClothType, CommonConstant.TYPE_BOTTOM_CLOTH).or().eq(SysFile::getClothType, CommonConstant.TYPE_DRESS) + .eq(SysFile::getUserId, loginUser.getId()))).or().eq(SysFile::getCommonClothType, "in_" + clothType)); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + //衣服库(公共,与个人无关) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(SysFile::getClothType, CommonConstant.TYPE_TOP_CLOTH) + .or().eq(SysFile::getClothType, CommonConstant.TYPE_BOTTOM_CLOTH).or() + .eq(SysFile::getClothType, CommonConstant.TYPE_DRESS))).or().eq(SysFile::getCommonClothType, "in_" + clothType)); + } + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + List sysFileListVO = new ArrayList<>(); + if (sysFileList != null && sysFileList.size() > 0) { + for (SysFile sysFile : sysFileList) { + Date createTime = sysFile.getCreateTime(); + boolean result = compareHour(createTime); + String fileStatus = sysFile.getFileStatus(); + if (("disable".equals(fileStatus) && result) || CommonConstant.FILE_STATUS_FAIL.equals(fileStatus)) { + sysFileMapper.deleteById(sysFile); + continue; + } + QueryClothTypeListVO queryClothTypeListVO = new QueryClothTypeListVO(); + queryClothTypeListVO.setFileStatus(sysFile.getFileStatus()); + queryClothTypeListVO.setClothType(sysFile.getClothType()); + queryClothTypeListVO.setBuyLink(sysFile.getBuyLink()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setClothId(sysFile.getId()); + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + Long count = sysFileMapper.selectCount(new QueryWrapper().lambda().eq(SysFile::getWardrobeId, sysFile.getId())); + if (count > 0) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_NO); + } + } + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + } + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 上传模特头像=="); + return Result.OK(sysFileListVO, taskId); + } + + + /////////////////////////////////////////////////////////////////////////////// + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + //我的衣橱(个人) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(oConvertUtils.isNotEmpty(clothType), SysFile::getClothType, clothType).eq(SysFile::getUserId, loginUser.getId()))).or().like(oConvertUtils.isNotEmpty(clothType), SysFile::getCommonClothType, "in_" + clothType).like(oConvertUtils.isEmpty(clothType), SysFile::getCommonClothType, "in_")); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + //衣服库(公共,与个人无关) + queryWrapper.lambda().and(w -> w.and((w1 -> w1.eq(oConvertUtils.isNotEmpty(clothType), SysFile::getClothType, clothType).isNotNull(SysFile::getId))).or().like(oConvertUtils.isNotEmpty(clothType), SysFile::getCommonClothType, "in_" + clothType).like(oConvertUtils.isEmpty(clothType), SysFile::getCommonClothType, "in_")); + } + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + List sysFileListVO = new ArrayList<>(); //用户返回前端 + // 假设sysFileMapper.selectObjs能够正确执行,并且返回了包含wardrobeId的List + List wardrobeIdList = sysFileMapper.selectObjs(new QueryWrapper().lambda().eq(SysFile::getUserId, loginUser.getId()).select(SysFile::getWardrobeId)); + // 将List转换为Set,自动去除重复项 + Set wardrobeIdSet = new HashSet<>(wardrobeIdList); + if (sysFileList != null && sysFileList.size() > 0) { + List filesToDelete = new ArrayList<>(); // 用于存储需要删除的文件ID + for (SysFile sysFile : sysFileList) { + Date createTime = sysFile.getCreateTime(); + boolean result = compareHour(createTime); + String fileStatus = sysFile.getFileStatus(); + if (("disable".equals(fileStatus) && result) || CommonConstant.FILE_STATUS_FAIL.equals(fileStatus)) { + filesToDelete.add(sysFile.getId()); + continue; + } + QueryClothTypeListVO queryClothTypeListVO = new QueryClothTypeListVO(); + queryClothTypeListVO.setFileStatus(sysFile.getFileStatus()); + queryClothTypeListVO.setClothType(sysFile.getClothType()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setBuyLink(sysFile.getBuyLink()); + queryClothTypeListVO.setClothId(sysFile.getId()); + if (CommonConstant.COMMON_YES.equals(queryClothTypeDTO.getIsPerson())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else if (CommonConstant.COMMON_NO.equals(queryClothTypeDTO.getIsPerson())) { + if (wardrobeIdSet.contains(sysFile.getId())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_NO); + } + } + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + // 批量删除文件 + if (!filesToDelete.isEmpty()) { + sysFileMapper.deleteBatchIds(filesToDelete); + } + } + log.info(loginUser.getUsername() + " === " + taskId + "== 返回 上传模特头像=="); + return Result.OK(sysFileListVO, taskId); + } + + @Override + public Result callBack(CallBackDTO callBackDTO) { + log.info("===开始 进入回调接口===" + callBackDTO); + if (null == callBackDTO) { + log.info("===返回数据不能为空==="); + return Result.error("返回数据不能为空!"); + } + String clothId = callBackDTO.getClothId(); + String status = "0".equals(callBackDTO.getStatus()) ? CommonConstant.FILE_STATUS_ENABLE : CommonConstant.FILE_STATUS_FAIL; + String taskId = callBackDTO.getTaskId(); + SysFile sysFile = sysFileMapper.selectById(clothId); + if (null == sysFile) { + log.info("===数据库中无此数据===" + taskId); + return Result.ok("数据库中无此数据!" + taskId); + } + sysFile.setFileStatus(status); + sysFileMapper.updateById(sysFile); + //查询如果有公共库的数据也要同时处理 + List sysFileList = sysFileMapper.selectList(new QueryWrapper().lambda().eq(SysFile::getMaterialPath, sysFile.getMaterialPath())); + if (sysFileList != null && sysFileList.size() > 0) { + for (SysFile sf : sysFileList) { + sf.setFileStatus(status); + sysFileMapper.updateById(sf); + } + } + log.info("===结束 回调接口处理完成!===" + taskId); + return Result.ok("回调成功!", taskId); + } + + @Override + public Result grabPicture(String crawlerUrl) { + boolean isUrl = AudioUtil.testUrlWithTimeOut(crawlerUrl, 2000); + if (!isUrl) { + return Result.error("请输入合法链接!"); + } + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info(taskId + "开始抓取图片== " + crawlerUrl); + JSONObject clothParam = new JSONObject(); + clothParam.put("vip_url", crawlerUrl); + clothParam.put("request_id", taskId); + String img_save_dir = uploaded_folder + "/crawler-datas/vip-datas/" + taskId; + clothParam.put("imgs_save_dir", img_save_dir); + log.info("算法 clothParam =" + clothParam); + JSONArray resultUrl; + try { + ResponseEntity clothResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.CRAWLER_VIP, HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = clothResult.getBody().get("status").toString(); + resultUrl = clothResult.getBody().getJSONArray("result"); + log.info(taskId + " 抓取图片 返回结果信息成功 ==" + taskId + " clothResult=" + clothResult.getBody()); + if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { + log.info(String.format("抓取图片 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + return Result.error(String.format("抓取图片 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + } + // 尝试将返回结果转为JSON + JSONObject jsonObject = clothResult.getBody(); + log.info("data=" + jsonObject); +// return Result.ok("调用成功!!!"); + } catch (Exception ex) { + String message = ex.getMessage(); + log.info("d抓取图片 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + return Result.error("抓取图片" + String.format("%s {taskId: %s}", message, taskId)); + } + /////////////////////////////////////////////////////////////////////////////////////// + List crawlerPictureVOS = new ArrayList<>(); + for (Object obj : resultUrl) { + String ci = (String) obj; + List uploadImages = uploadImagesInFolder(ci); + log.info("图片路径:=" + uploadImages); + if (uploadImages != null && uploadImages.size() > 0) { + for (String imagePath : uploadImages) { + File file = new File(imagePath); + String newFileName = UUID.randomUUID().toString() + file.getName().substring(file.getName().lastIndexOf(".")); + String videoUrl = OssBootUtil.uploadOssVideo(file, CommonConstant.FILE_TYPE_VIDEO, newFileName); + String savePath = OssBootUtil.getDigitalObjectURL(ossConfiguration.getBucketName(), videoUrl, null); + String thumbnailURL = OssBootUtil.getObjectThumbnailURL(ossConfiguration.getBucketName(), videoUrl); + log.info("oss 图片 savePath=" + savePath); + SysFile sysFile = new SysFile(); + sysFile.setFileUrl(savePath); + sysFile.setIsTemp("1"); + sysFile.setUserId(loginUser.getId()); + sysFile.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sysFile.setFilePath(imagePath); + sysFile.setFileType(CommonConstant.CLOTH_FILE_TYPE); + sysFile.setThumbnailFileUrl(thumbnailURL); + sysFileMapper.insert(sysFile); + /////////////////////// + CrawlerPictureVO crawlerPictureVO = new CrawlerPictureVO(); + crawlerPictureVO.setId(sysFile.getId()); + crawlerPictureVO.setFileUrl(savePath); + crawlerPictureVO.setThumbnailFileUrl(thumbnailURL); + crawlerPictureVOS.add(crawlerPictureVO); + } + } + } + return Result.ok(crawlerPictureVOS, taskId); + } + + @Override + public Result tryOn(TryOnDTO tryOns) { + String batchNo = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + List tryOnDTOList = tryOns.getTryOnList(); + String tryOnType; + if (1 == tryOnDTOList.size()) { + tryOnType = CommonConstant.TRY_ON_TYPE_SINGLE; + } else { + tryOnType = CommonConstant.TRY_ON_TYPE_BATCH; + } + String tryOnAlgo = null; + boolean found = false; + for (TryOnDTO.TryOn tryOn : tryOnDTOList) { + List clothIds = tryOn.getClothIds(); + for (String clothId : clothIds) { + SysFile sysFile = sysFileMapper.selectById(clothId); + //看看是不是换发型 + if (sysFile != null && CommonConstant.TYPE_HAIR.equals(sysFile.getClothType())) { + tryOnAlgo = CommonConstant.TRY_ON_TYPE_ALGO_HAIR; + found = true; + break; + } + //看看是不是换身材 + if (sysFile != null && CommonConstant.TYPE_FIGURE.equals(sysFile.getClothType())) { + tryOnAlgo = CommonConstant.TYPE_FIGURE; + found = true; + break; + } + //看看是不是换内衣 + if (sysFile != null && CommonConstant.TYPE_UNDERWEAR.equals(sysFile.getClothType())) { + tryOnAlgo = CommonConstant.TYPE_UNDERWEAR; + found = true; + break; + } + } + if (found) break; + } + if (oConvertUtils.isEmpty(tryOnAlgo)) { + tryOnAlgo = CommonConstant.TRY_ON_TYPE_ALGO_CLOTH; + } + //批量添加对应的数据 + List sysHistoryList = new ArrayList<>(); + for (int i = 0; i < tryOnDTOList.size(); i++) { + SysHistory sysHistory = new SysHistory(); + sysHistory.setFileUrl(TRY_ON_IN_PROCESS); + sysHistory.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + sysHistory.setBatchNo(batchNo); + sysHistory.setTryOnType(tryOnType); + sysHistory.setTryOnAlgo(tryOnAlgo); + sysHistory.setUserId(loginUser.getId()); + sysHistory.setCreateTime(new Date()); + sysHistoryList.add(sysHistory); + } + sysHistoryService.saveBatch(sysHistoryList); + log.info("开始同步任务" + batchNo); + ////////////////// 开始处理换内衣 ///////////////////// + if (CommonConstant.TYPE_UNDERWEAR.equals(tryOnAlgo)) { + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + return Result.error("数据库中无此数据! modelId=" + modelId, taskId); + } + List clothIds = tryOnDTO.getClothIds(); + for (String clothId : clothIds) { + SysFile cloth = sysFileMapper.selectById(clothId); + if (cloth == null) { + log.info(taskId + "数据库中无此数据! clothId=" + clothId); + return Result.error("数据库中无此数据! clothId=" + clothId, taskId); + } + taskId = UUID.randomUUID().toString(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setTryOnAlgo(tryOnAlgo); + trainTask.setUserId(loginUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(clothId); + trainTask.setModelPath(modelImage.getFilePath()); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + log.info("sysHistory===" + sysHistory); + //添加完毕 + JSONObject clothParam = new JSONObject(); + clothParam.put("task_id", taskId); + clothParam.put("userImgPath", modelImage.getFilePath()); + clothParam.put("gender", "female"); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setTryOnAlgo(tryOnAlgo); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(loginUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueue.setIsHr(tryOns.getIsHr()); + sysTaskQueueMapper.insert(sysTaskQueue); + log.info("提交成功!sysTaskQueue==" + sysTaskQueue); + } + } + return Result.ok("提交成功!", batchNo); + } + ////////////////// 开始处理换身材 ///////////////////// + if (CommonConstant.TYPE_FIGURE.equals(tryOnAlgo)) { + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + return Result.error("数据库中无此数据! modelId=" + modelId, taskId); + } + List clothIds = tryOnDTO.getClothIds(); + for (String clothId : clothIds) { + SysFile cloth = sysFileMapper.selectById(clothId); + if (cloth == null) { + log.info(taskId + "数据库中无此数据! clothId=" + clothId); + return Result.error("数据库中无此数据! clothId=" + clothId, taskId); + } + taskId = UUID.randomUUID().toString(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setTryOnAlgo(tryOnAlgo); + trainTask.setUserId(loginUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(clothId); + trainTask.setModelPath(modelImage.getFilePath()); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + log.info("sysHistory===" + sysHistory); + //添加完毕 + JSONObject clothParam = new JSONObject(); + clothParam.put("input_img_url", modelImage.getFileUrl()); + clothParam.put("strong_strength", cloth.getRepValue()); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setTryOnAlgo(tryOnAlgo); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(loginUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueue.setIsHr(tryOns.getIsHr()); + sysTaskQueueMapper.insert(sysTaskQueue); + log.info("提交成功!sysTaskQueue==" + sysTaskQueue); + } + } + return Result.ok("提交成功!", batchNo); + } + + ////////////////// 开始处理换发型 ///////////////////// + if (CommonConstant.TRY_ON_TYPE_ALGO_HAIR.equals(tryOnAlgo)) { + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + return Result.error("数据库中无此数据! modelId=" + modelId, taskId); + } + List clothIds = tryOnDTO.getClothIds(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setTryOnAlgo(tryOnAlgo); + trainTask.setUserId(loginUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(String.join(",", clothIds)); + trainTask.setModelPath(modelImage.getFilePath()); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + log.info("sysHistory===" + sysHistory); + //添加完毕 + JSONObject clothParam = new JSONObject(); + for (String clothId : clothIds) { + SysFile clothImage = sysFileMapper.selectWithoutLogicDeleteById(clothId); + if (null == clothImage) { + continue; + } + clothParam.put("hair_id", CommonUtils.checkAndReplaceLastSegment(clothImage.getMaterialPath(), clothId)); + clothParam.put("hair_material_dir", clothImage.getMaterialPath()); + } + clothParam.put("task_id", taskId); + clothParam.put("is_hr", tryOns.getIsHr()); + clothParam.put("user_img_path", modelImage.getFilePath()); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setTryOnAlgo(tryOnAlgo); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(loginUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueue.setIsHr(tryOns.getIsHr()); + sysTaskQueueMapper.insert(sysTaskQueue); + log.info("提交成功!sysTaskQueue==" + sysTaskQueue); + } + return Result.ok("提交成功!", batchNo); + } + ////////////////// 开始处理试穿 ///////////////////// + for (int i = 0; i < tryOnDTOList.size(); i++) { + String taskId = UUID.randomUUID().toString(); + TryOnDTO.TryOn tryOnDTO = tryOnDTOList.get(i); + SysHistory sysHistory = sysHistoryList.get(i); + String modelId = tryOnDTO.getModelId(); + SysFile modelImage = sysFileMapper.selectById(modelId); + if (modelImage == null) { + log.info(taskId + "数据库中无此数据! modelId=" + modelId); + continue; + } + List clothIds = tryOnDTO.getClothIds(); + JSONObject jsonObject = new JSONObject(); + MwTrainTask trainTask = new MwTrainTask(); + trainTask.setTaskId(taskId); + trainTask.setTryOnType(tryOnType); + trainTask.setUserId(loginUser.getId()); + trainTask.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_IN_PROGRESS); + trainTask.setClothPath(String.join(",", clothIds)); + trainTaskMapper.insert(trainTask); + //给历史记录添加taskid + sysHistory.setTaskId(taskId); + sysHistoryMapper.updateById(sysHistory); + //添加完毕 + int size = clothIds.size(); + if (size == 1) { + for (String clothId : clothIds) { + SysFile clothImage = sysFileMapper.selectById(clothId); + if (clothImage != null) { + if ("topCloth".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); + jsonObject.put("upper", list); + jsonObject.put("lower", ""); + } + if ("bottomCloth".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "1", clothImage.getProcessType()); + jsonObject.put("upper", ""); + jsonObject.put("lower", list); + } + if ("dress".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "2", clothImage.getProcessType()); + jsonObject.put("upper", list); + jsonObject.put("lower", ""); + } + } + } + } + if (size == 2) { + if (clothIds != null && clothIds.size() > 0) { + for (String clothId : clothIds) { + SysFile clothImage = sysFileMapper.selectById(clothId); + if (clothImage != null) { + if ("topCloth".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); + jsonObject.put("upper", list); + } + if ("bottomCloth".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); + jsonObject.put("lower", list); + } + if ("dress".equals(clothImage.getClothType())) { + List list = Arrays.asList(clothImage.getMaterialPath(), "0", clothImage.getProcessType()); + jsonObject.put("upper", list); + jsonObject.put("lower", ""); + } + } + } + } + } + trainTask.setModelPath(modelImage.getFilePath()); + JSONObject clothParam = new JSONObject(); + clothParam.put("task_id", taskId); + clothParam.put("userImgPath", modelImage.getFilePath()); + if (oConvertUtils.isNotEmpty(modelImage.getSex())) { + clothParam.put("sex", modelImage.getSex()); + } else { + clothParam.put("sex", "female"); + } + clothParam.put("data_dict", jsonObject); + SysTaskQueue sysTaskQueue = new SysTaskQueue(); + sysTaskQueue.setTaskId(taskId); + sysTaskQueue.setTryOnType(tryOnType); + sysTaskQueue.setStatus(Face3dSeverHTTPConstant.CREATE_STATUS_DRAFT); + sysTaskQueue.setUserId(loginUser.getId()); + sysTaskQueue.setJsonInfo(clothParam.toJSONString()); + sysTaskQueue.setSex(modelImage.getSex()); + sysTaskQueueMapper.insert(sysTaskQueue); + } + return Result.ok("提交成功!", batchNo); + } + + @Override + public Result getModelList(GetModelDTO getModelDTO) { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.info(loginUser.getUsername() + "==开始查询获取模特列表==" + taskId); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getFileType, CommonConstant.MODEL_FILE_TYPE); + queryWrapper.lambda().eq(SysFile::getSex, getModelDTO.getSex()); + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + queryWrapper.lambda().and(w1 -> w1.eq(SysFile::getUserId, loginUser.getId()).or().eq(SysFile::getCommonClothType, "in_model")); + queryWrapper.last("LIMIT 50"); + List sysFileList = sysFileMapper.selectList(queryWrapper); + List modelListVOList = new ArrayList<>(); + if (sysFileList != null && sysFileList.size() > 0) { + for (SysFile sysFile : sysFileList) { + GetModelListVO queryClothTypeListVO = new GetModelListVO(); + queryClothTypeListVO.setId(sysFile.getId()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + modelListVOList.add(queryClothTypeListVO); + } + return Result.OK(modelListVOList, taskId); + } + log.info(loginUser.getUsername() + "===" + taskId + "==返回 获取模特列表==" + modelListVOList); + return Result.OK(modelListVOList, taskId); + } + + @Override + public Result uploadCloth(UploadClothDTO uploadClothDTO) { + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + String clothType = uploadClothDTO.getClothType(); + List clothFileList = uploadClothDTO.getClothFileList(); + log.info(loginUser.getUsername() + " === 开始上传图片分类" + uploadClothDTO); + if (CollectionUtil.isEmpty(clothFileList)) { + log.info(loginUser.getUsername() + " === 上传图片不能为空!"); + return Result.error("上传图片不能为空!"); + } + //处理发型上传 + if (CommonConstant.TYPE_HAIR.equals(clothType)) { + String taskId = UUID.randomUUID().toString(); + log.info("处理发型上传"); + String fileId = clothFileList.get(0); + SysFile sysFile = sysFileMapper.selectById(fileId); + if (sysFile == null) { + log.info(loginUser.getUsername() + " === " + taskId + "数据库中无此数据!"); + return Result.error("数据库中无此数据!", taskId); + } + sysFile.setClothType(clothType); + sysFile.setFileType(CommonConstant.HAIR_FILE_TYPE); + sysFile.setIsPerson(CommonConstant.COMMON_YES); + if (clothFileList.size() == 1) { + sysFile.setProcessType("single"); + } else { + sysFile.setProcessType("multi"); + } + sysFile.setSex(uploadClothDTO.getSex()); + sysFile.setIsTemp("0"); + sysFile.setUserId(loginUser.getId()); + String data_path = uploaded_folder + "/material_path/" + fileId; + try { + Path path = Paths.get(data_path); + if (path != null && !Files.exists(path)) { + Files.createDirectories(path); + } + } catch (IOException e) { + log.info(loginUser.getUsername() + " === " + taskId + "目录创建失败:", e); + log.info(taskId + " 图片落盘失败 ========================" + String.format("图片落盘失败!{taskId: %s}", taskId)); + return Result.error("图片落盘失败!", taskId); + } + sysFile.setMaterialPath(data_path); + if (clothFileList.size() == 1) { + sysFile.setProcessType("single"); + } else { + sysFile.setProcessType("multi"); + } + sysFileMapper.updateById(sysFile); + //调用算法 + List clothPathList = new ArrayList<>(); + for (String clothFile : clothFileList) { + SysFile clothFileSysFile = sysFileMapper.selectById(clothFile); + if (clothFileSysFile != null) { + clothPathList.add(clothFileSysFile.getFilePath()); + } + } + JSONObject clothParam = new JSONObject(); + clothParam.put("task_id", taskId); + clothParam.put("img_lists", clothPathList); + clothParam.put("hair_id", fileId); + clothParam.put("data_path", data_path); + log.info("算法 发型素材上传 =" + clothParam); + try { + ResponseEntity clothResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.HAIR_UPLOAD, HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = clothResult.getBody().get("state").toString(); + log.info(taskId + " 返回结果信息成功 ==" + taskId + " 发型素材上传返回=" + clothResult.getBody()); + if (!"0".equals(clothState)) { + log.info(String.format("发型素材上传 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + return Result.error(String.format("发型素材上传 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + } + } catch (Exception ex) { + String message = ex.getMessage(); + log.info("发型素材上传 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + return Result.error("发型素材上传 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + } + //开始 同步到衣服库 + if (CommonConstant.COMMON_YES.equals(uploadClothDTO.getIsSync())) { + //同步到衣服库 + SysFile sf = sysFileMapper.selectById(fileId); + if (sf != null) { + sf.setId(null); + sf.setIsPerson(CommonConstant.COMMON_NO); + sf.setIsTemp("0"); + sf.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sf.setCreateTime(null); + sf.setUpdateTime(null); + sysFileMapper.insert(sf); + } + } + //结束 同步到衣服库 + return Result.ok("发型素材上传成功!"); + } + + // 处理衣服上传 + for (String fileId : clothFileList) { + // 任务执行后等待3秒 + long startTime = System.currentTimeMillis(); + try { + Thread.sleep(3000); // 暂停3秒 + } catch (InterruptedException e) { + // 如果线程在等待过程中被中断,则处理异常 + log.error("线程被中断:" + e.getMessage()); + break; // 退出循环 + } + String taskId = UUID.randomUUID().toString(); + SysFile sysFile = sysFileMapper.selectById(fileId); + if (sysFile == null) { + log.info(loginUser.getUsername() + " === " + taskId + "数据库中无此数据!==fileId==" + fileId); + continue; + } + sysFile.setClothType(clothType); + sysFile.setIsTemp("0"); + sysFile.setUserId(loginUser.getId()); + String data_path = uploaded_folder + "/material_path/" + fileId; + try { + Path path = Paths.get(data_path); + if (path != null && !Files.exists(path)) { + Files.createDirectories(path); + } + } catch (IOException e) { + log.info(loginUser.getUsername() + " === " + taskId + "目录创建失败:", e); + log.info(taskId + " 音频落盘失败 ========================" + String.format("音频落盘失败!{taskId: %s}", taskId)); + continue; + } + sysFile.setMaterialPath(data_path); + sysFile.setIsPerson(CommonConstant.COMMON_YES); + if (clothFileList.size() == 1) { + sysFile.setProcessType("single"); + } else { + sysFile.setProcessType("multi"); + } + sysFile.setSex(uploadClothDTO.getSex()); + sysFileMapper.updateById(sysFile); + //调用算法 + JSONObject clothParam = new JSONObject(); + clothParam.put("task_id", taskId); + if (clothFileList.size() == 1) { + clothParam.put("type", "single"); + } else { + clothParam.put("type", "multi"); + } + clothParam.put("imgLists", Arrays.asList(sysFile.getFilePath())); + clothParam.put("cloth_id", fileId); + clothParam.put("data_path", data_path); + if (oConvertUtils.isNotEmpty(sysFile.getSex())) { + clothParam.put("sex", sysFile.getSex()); + } else { + clothParam.put("sex", "female"); + } + log.info("算法 clothParam =" + clothParam); + try { + ResponseEntity clothResult = RestUtil.zitaRequest(Face3dSeverHTTPConstant.CLOTH_UPLOAD, HttpMethod.POST, null, clothParam, JSONObject.class); + String clothState = clothResult.getBody().get("status").toString(); + log.info(taskId + " 返回结果信息成功 ==" + taskId + " clothResult=" + clothResult.getBody()); + if (!ZitaCommonConstant.STATUS_NORMAL.equals(clothState)) { + log.info(String.format("上传图片分类 任务失败!{taskId: %s, resp: %s}", taskId, clothResult.getBody().toJSONString())); + continue; + } + log.info("调用成功!!! "); + } catch (Exception ex) { + String message = ex.getMessage(); + log.info("上传图片分类 任务失败!" + String.format("%s {taskId: %s}", message, taskId)); + } + } + //开始 同步到衣服库 + if (CommonConstant.COMMON_YES.equals(uploadClothDTO.getIsSync())) { + //同步到衣服库 + for (String clothId : clothFileList) { + SysFile sf = sysFileMapper.selectById(clothId); + if (sf != null) { + sf.setId(null); + sf.setIsPerson(CommonConstant.COMMON_NO); + sf.setIsTemp("0"); + sf.setFileStatus(CommonConstant.FILE_STATUS_DISABLE); + sf.setCreateTime(null); + sf.setUpdateTime(null); + sysFileMapper.insert(sf); + } + } + } + //结束 同步到衣服库 + return Result.ok("上传图片分类成功!"); + } + + + /** + * 衣服类型图片-分页列表查询 + * + * @param page + * @param clothType + * @return + */ + @Override + public Result queryClothTypeList(Page page, String clothType) { + String taskId = UUID.randomUUID().toString(); + log.info(taskId + "开始 衣服类型图片-分页列表查询 "); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(oConvertUtils.isNotEmpty(clothType), SysFile::getClothType, clothType); + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + IPage clothTypeList = sysFileMapper.queryClothTypeList(page, queryWrapper); + List records = clothTypeList.getRecords(); + if (records == null || records.size() == 0) { + IPage p = new Page<>(); + if (loginUser != null) { + log.info(loginUser.getUsername() + "结束 衣服类型图片-分页列表查询,无数据!" + taskId); + } + return Result.OK(p, taskId); + } + return Result.OK(clothTypeList, taskId); + } + +} diff --git a/digital-application/src/main/java/digital/application/service/impl/SysHistoryServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/SysHistoryServiceImpl.java new file mode 100644 index 0000000..d9652ac --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/SysHistoryServiceImpl.java @@ -0,0 +1,13 @@ +package digital.application.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.entity.SysHistory; +import digital.application.mapper.SysHistoryMapper; +import digital.application.service.SysHistoryService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class SysHistoryServiceImpl extends ServiceImpl implements SysHistoryService { +} diff --git a/digital-application/src/main/java/digital/application/service/impl/SysRoomServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/SysRoomServiceImpl.java new file mode 100644 index 0000000..9cfc503 --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/SysRoomServiceImpl.java @@ -0,0 +1,199 @@ +package digital.application.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.dto.*; +import digital.application.entity.SysFile; +import digital.application.entity.SysRoom; +import digital.application.entity.SysRoomCloth; +import digital.application.mapper.SysFileMapper; +import digital.application.mapper.SysRoomClothMapper; +import digital.application.mapper.SysRoomMapper; +import digital.application.service.SysRoomService; +import digital.application.vo.GetRoomListVO; +import digital.application.vo.QueryClothTypeListVO; +import digital.base.constant.CommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +import static digital.application.utils.TimeUtils.compareHour; + +@Slf4j +@Service +public class SysRoomServiceImpl extends ServiceImpl implements SysRoomService { + + @Autowired + private SysRoomMapper sysRoomMapper; + @Autowired + private SysRoomClothMapper sysRoomClothMapper; + @Autowired + private SysFileMapper sysFileMapper; + + @Override + public Result delRoomCloth(AddRoomClothDTO addRoomClothDTO) { + String taskId = UUID.randomUUID().toString(); + SysRoomCloth sysRoomCloth = sysRoomClothMapper.selectOne(new QueryWrapper().lambda() + .eq(SysRoomCloth::getRoomId, addRoomClothDTO.getRoomId()) + .eq(SysRoomCloth::getFileId, addRoomClothDTO.getClothId())); + if (null == sysRoomCloth) { + return Result.error("该试衣间不存在该衣服!", taskId); + } + sysRoomClothMapper.deleteById(sysRoomCloth.getId()); + return Result.OK("删除成功!", taskId); + } + + + @Override + public Result addRoomCloth(AddRoomClothDTO addRoomClothDTO) { + String taskId = UUID.randomUUID().toString(); + Long count = sysRoomClothMapper.selectCount(new QueryWrapper().lambda() + .eq(SysRoomCloth::getRoomId, addRoomClothDTO.getRoomId()) + .eq(SysRoomCloth::getFileId, addRoomClothDTO.getClothId())); + if (count > 0) { + return Result.error("该试衣间已添加该衣服!", taskId); + } + SysRoomCloth sysRoomCloth = new SysRoomCloth(); + sysRoomCloth.setFileId(addRoomClothDTO.getClothId()); + sysRoomCloth.setRoomId(addRoomClothDTO.getRoomId()); + sysRoomClothMapper.insert(sysRoomCloth); + return Result.ok("添加成功!", taskId); + } + + @Override + public Result getRoomClothList(GetRoomClothListDTO getRoomClothListDTO) { + String taskId = UUID.randomUUID().toString(); + String roomId = getRoomClothListDTO.getRoomId(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + SysRoom sysRoom = sysRoomMapper.selectById(roomId); + if (null == sysRoom) { + return Result.OK("数据库中不存在该试衣间!", taskId); + } + //查询本人试衣间的衣服id + List fileIds = new ArrayList<>(); + List sysRoomCloths = sysRoomClothMapper.selectList(new QueryWrapper().lambda().eq(SysRoomCloth::getRoomId, roomId)); + if (null != sysRoomCloths && sysRoomCloths.size() > 0) { + fileIds = sysRoomCloths.stream() + .map(SysRoomCloth::getFileId) + .collect(Collectors.toList()); + } + //查询我的衣橱全部衣服 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysFile::getIsTemp, "0"); + queryWrapper.lambda().eq(SysFile::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(SysFile::getFileType, CommonConstant.CLOTH_FILE_TYPE); + queryWrapper.lambda().eq(SysFile::getIsPerson, CommonConstant.COMMON_YES); + queryWrapper.lambda().eq(SysFile::getSex, getRoomClothListDTO.getSex()); + queryWrapper.lambda().and( + w -> w.and( + (w1 -> w1.eq(SysFile::getUserId, loginUser.getId())) + ) + .or() + .like(SysFile::getCommonClothType, "in_") + ); + queryWrapper.lambda().orderByDesc(SysFile::getCreateTime); + List sysFileList = sysFileMapper.selectList(queryWrapper); + List sysFileListVO = new ArrayList<>(); + if (sysFileList != null && sysFileList.size() > 0) { + for (SysFile sysFile : sysFileList) { + Date createTime = sysFile.getCreateTime(); + boolean result = compareHour(createTime); + String fileStatus = sysFile.getFileStatus(); + if ("disable".equals(fileStatus) && result) { + sysFileMapper.deleteById(sysFile); + continue; + } + QueryClothTypeListVO queryClothTypeListVO = new QueryClothTypeListVO(); + queryClothTypeListVO.setFileStatus(sysFile.getFileStatus()); + queryClothTypeListVO.setClothType(sysFile.getClothType()); + queryClothTypeListVO.setFileUrl(sysFile.getFileUrl()); + queryClothTypeListVO.setClothId(sysFile.getId()); + if (fileIds.contains(sysFile.getId())) { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_YES); + } else { + queryClothTypeListVO.setIsHas(CommonConstant.COMMON_NO); + } + queryClothTypeListVO.setThumbnailFileUrl(sysFile.getThumbnailFileUrl()); + sysFileListVO.add(queryClothTypeListVO); + } + } + return Result.OK(sysFileListVO, taskId); + } + + @Override + public Result getRoomList(GetRoomListDTO getRoomListDTO) { + String taskId = UUID.randomUUID().toString(); + List getRoomListVOList = new ArrayList<>(); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + queryWrapper.lambda().eq(SysRoom::getUserId, loginUser.getId()); + queryWrapper.lambda().eq(SysRoom::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(oConvertUtils.isNotEmpty(getRoomListDTO.getSex()), SysRoom::getSex, getRoomListDTO.getSex()); + queryWrapper.lambda().orderByDesc(SysRoom::getCreateTime); + List sysRooms = sysRoomMapper.selectList(queryWrapper); + if (null != sysRooms && sysRooms.size() > 0) { + for (SysRoom sysRoom : sysRooms) { + GetRoomListVO getRoomListVO = new GetRoomListVO(); + getRoomListVO.setCreateTime(sysRoom.getCreateTime()); + getRoomListVO.setRoomId(sysRoom.getId()); + getRoomListVO.setSex(sysRoom.getSex()); + getRoomListVO.setRoomName(sysRoom.getRoomName()); + getRoomListVOList.add(getRoomListVO); + } + return Result.OK(getRoomListVOList, taskId); + } + return Result.OK(getRoomListVOList, taskId); + } + + + @Override + public Result addRoom(AddRoomDTO addRoomDTO) { + String taskId = UUID.randomUUID().toString(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + Long count = sysRoomMapper.selectCount(new QueryWrapper().lambda().eq(SysRoom::getUserId, loginUser.getId())); + if (count >= 7) { + return Result.error("最多只能创建7个试衣间!", taskId); + } + SysRoom sysRoom = new SysRoom(); + sysRoom.setRoomName(addRoomDTO.getRoomName()); + sysRoom.setUserId(loginUser.getId()); + sysRoom.setSex(addRoomDTO.getSex()); + sysRoomMapper.insert(sysRoom); + return Result.OK("添加成功!", taskId); + } + + @Override + public Result delRoom(DelRoomDTO delRoomDTO) { + String taskId = UUID.randomUUID().toString(); + SysRoom sysRoom = sysRoomMapper.selectById(delRoomDTO.getRoomId()); + if (null == sysRoom) { + return Result.error("数据库中无此数据!", taskId); + } + sysRoomMapper.deleteById(sysRoom.getId()); + return Result.OK("删除成功!", taskId); + } + + @Override + public Result updateRoom(UpdateRoomDTO updateRoomDTO) { + String taskId = UUID.randomUUID().toString(); + SysRoom sysRoom = sysRoomMapper.selectById(updateRoomDTO.getRoomId()); + if (null == sysRoom) { + return Result.error("数据库中无此数据!", taskId); + } + sysRoom.setRoomName(updateRoomDTO.getRoomName()); + sysRoomMapper.updateById(sysRoom); + return Result.OK("修改成功!", taskId); + } + +} diff --git a/digital-application/src/main/java/digital/application/service/impl/SysTaskQueueServiceImpl.java b/digital-application/src/main/java/digital/application/service/impl/SysTaskQueueServiceImpl.java new file mode 100644 index 0000000..dea42dc --- /dev/null +++ b/digital-application/src/main/java/digital/application/service/impl/SysTaskQueueServiceImpl.java @@ -0,0 +1,15 @@ +package digital.application.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.application.entity.SysTaskQueue; +import digital.application.mapper.SysTaskQueueMapper; +import digital.application.service.SysTaskQueueService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class SysTaskQueueServiceImpl extends ServiceImpl implements SysTaskQueueService { + + +} diff --git a/digital-application/src/main/java/digital/application/utils/AudioUtil.java b/digital-application/src/main/java/digital/application/utils/AudioUtil.java new file mode 100644 index 0000000..213884d --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/AudioUtil.java @@ -0,0 +1,120 @@ +package digital.application.utils; + +import org.jaudiotagger.audio.AudioFileIO; +import org.jaudiotagger.audio.mp3.MP3AudioHeader; +import org.jaudiotagger.audio.mp3.MP3File; + +import javax.sound.sampled.AudioFormat; +import javax.sound.sampled.AudioInputStream; +import javax.sound.sampled.AudioSystem; +import java.io.File; +import java.net.URL; +import java.net.URLConnection; + +public class AudioUtil { + + public static boolean testUrlWithTimeOut(String urlString, int timeOutMillSeconds) { + URL url; + try { + url = new URL(urlString); + URLConnection co = url.openConnection(); + co.setConnectTimeout(timeOutMillSeconds); + co.connect(); + return true; + } catch (Exception e1) { + url = null; + return false; + } + } + + /** + * 获取语音文件播放时长(秒) 支持wav 格式 + * + * @param filePath + * @return + */ + public static Float getDuration(String filePath) { + try { + + File destFile = new File(filePath); + AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(destFile); + AudioFormat format = audioInputStream.getFormat(); + long audioFileLength = destFile.length(); + int frameSize = format.getFrameSize(); + float frameRate = format.getFrameRate(); + float durationInSeconds = (audioFileLength / (frameSize * frameRate)); + return durationInSeconds; + + } catch (Exception e) { + e.printStackTrace(); + return 0f; + } + + } + + /** + * 获取mp3语音文件播放时长(秒) mp3 + * + * @param filePath + * @return + */ + public static Float getMp3Duration(String filePath) { + + try { + File mp3File = new File(filePath); + MP3File f = (MP3File) AudioFileIO.read(mp3File); + MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader(); + return Float.parseFloat(audioHeader.getTrackLength() + ""); + } catch (Exception e) { + e.printStackTrace(); + return 0f; + } + } + + + /** + * 获取mp3语音文件播放时长(秒) + * + * @param mp3File + * @return + */ + public static Float getMp3Duration(File mp3File) { + + try { + //File mp3File = new File(filePath); + MP3File f = (MP3File) AudioFileIO.read(mp3File); + MP3AudioHeader audioHeader = (MP3AudioHeader) f.getAudioHeader(); + return Float.parseFloat(audioHeader.getTrackLength() + ""); + } catch (Exception e) { + e.printStackTrace(); + return 0f; + } + } + + + /** + * 得到pcm文件的毫秒数 + *

+ * pcm文件音频时长计算 + * 同图像bmp文件一样,pcm文件保存的是未压缩的音频信息。 16bits 编码是指,每次采样的音频信息用2个字节保存。可以对比下bmp文件用分别用2个字节保存RGB颜色的信息。 16000采样率 是指 1秒钟采样 16000次。常见的音频是44100HZ,即一秒采样44100次。 单声道: 只有一个声道。 + *

+ * 根据这些信息,我们可以计算: 1秒的16000采样率音频文件大小是 2*16000 = 32000字节 ,约为32K 1秒的8000采样率音频文件大小是 2*8000 = 16000字节 ,约为 16K + *

+ * 如果已知录音时长,可以根据文件的大小计算采样率是否正常。 + * + * @param filePath + * @return + */ + public static long getPCMDurationMilliSecond(String filePath) { + File file = new File(filePath); + + //得到多少秒 + long second = file.length() / 32000; + + long milliSecond = Math.round((file.length() % 32000) / 32000.0 * 1000); + + return second * 1000 + milliSecond; + } + + +} diff --git a/digital-application/src/main/java/digital/application/utils/AuthInterceptor.java b/digital-application/src/main/java/digital/application/utils/AuthInterceptor.java new file mode 100644 index 0000000..68e9d0f --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/AuthInterceptor.java @@ -0,0 +1,55 @@ +//package digital.application.utils; +// +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import digital.base.constant.CommonConstant; +//import digital.system.jeecg.system.entity.SysUser; +//import digital.system.jeecg.system.service.ISysUserService; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Component; +//import org.springframework.web.servlet.HandlerInterceptor; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.util.Enumeration; +// +// +//@Component +//@Slf4j +//public class AuthInterceptor implements HandlerInterceptor { +// +// @Autowired +// private ISysUserService sysUserService; +// +// @Override +// public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { +// // 从请求中获取账号和密码 +// String appKey = request.getHeader("appKey"); +// String appSecret = request.getHeader("appSecret"); +// log.info("开始鉴权 appKey ="+appKey+" appSecret"+appSecret); +// // 调用UserService来验证账号和密码 +// QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.lambda().eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0); +// queryWrapper.lambda().eq(SysUser::getAppKey,appKey); +// queryWrapper.lambda().eq(SysUser::getAppSecret,appSecret); +// SysUser sysUser = sysUserService.getOne(queryWrapper); +// log.info("登录用户信息="+sysUser); +// // 打印通过HttpServletRequest获取的参数 +// Enumeration paramNames = request.getParameterNames(); +// while (paramNames.hasMoreElements()) { +// String paramName = paramNames.nextElement(); +// String paramValue = request.getParameter(paramName); +// log.info("Parameter Name: " + paramName +" Parameter Value: "+paramValue); +// } +// if (null == sysUser) { +// log.info("验证失败,返回错误信息"); +// // 验证失败,返回错误信息 +// response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "非法访问,请输入秘钥信息!!!"); +// return false; // 拦截请求,不继续执行 +// } +// log.info("验证通过,继续执行请求"); +// // 验证通过,继续执行请求 +// return true; +// } +// +//} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/utils/CloudStorageService.java b/digital-application/src/main/java/digital/application/utils/CloudStorageService.java new file mode 100644 index 0000000..1de4a7b --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/CloudStorageService.java @@ -0,0 +1,116 @@ +package digital.application.utils; + +import com.volcengine.tos.*; +import com.volcengine.tos.auth.StaticCredentials; +import com.volcengine.tos.model.object.PutObjectInput; +import com.volcengine.tos.model.object.PutObjectOutput; +import com.volcengine.tos.transport.TransportConfig; + +import java.io.InputStream; + + +public class CloudStorageService { + static Long startTime = 0l; + + static Long endTime = 0l; + + static String bucketPath = "hair/result/image/"; + + private static TOSV2 tosClient = null; + + private static TOSV2 getInstance() { + if (tosClient == null) { + tosClient = createTosClient(); + } + return tosClient; + + } + + private static TOSV2 createTosClient() { + String endpoint = "tos-accelerate.volces.com"; + String region = "ap-southeast-1"; + String accessKey = "AKLTMDA2YjdiNGRmZDJmNGM2Y2JiYTA2MDFmZTVhMGU2Yzc"; + String secretKey = "WWpnMk1HWmxZV1l3TWpVME5EazJZemxtTkRrMU1ERTVNV0pqWlRFMFpqYw=="; + + int idleConnectionTimeMills = 60000; + int maxConnections = 64; + + TransportConfig config = TransportConfig.builder() + .idleConnectionTimeMills(idleConnectionTimeMills) + .maxConnections(maxConnections) + .build(); + TOSClientConfiguration configuration = TOSClientConfiguration.builder() + .transportConfig(config) + .region(region) + .endpoint(endpoint) + .credentials(new StaticCredentials(accessKey, secretKey)) + .build(); + + TOSV2 tos = new TOSV2ClientBuilder().build(configuration); + return tos; + } + + + private static boolean saveByteDanceTos(String fileName, InputStream inputStream) { + + startTime = System.currentTimeMillis(); + TOSV2 tos = getInstance(); + endTime = System.currentTimeMillis(); + startTime = System.currentTimeMillis(); + + String bucketName = "hairstyle"; + // TOSV2 提供的所有接口均会抛出 TosException 异常,需要使用 try-catch 进行捕获并处理。 + try { + // 设置上传的桶名和对象名 + String objKey = bucketPath + fileName; + + PutObjectInput putObjectInput = new PutObjectInput().setBucket(bucketName).setKey(objKey).setContent(inputStream); + // 上传对象 + PutObjectOutput output = tos.putObject(putObjectInput); + + endTime = System.currentTimeMillis(); + + return true; + } catch (TosClientException e) { + // 操作失败,捕获客户端异常,一般情况是请求参数错误,此时请求并未发送 + System.out.println("putObject failed"); + System.out.println("Message: " + e.getMessage()); + if (e.getCause() != null) { + e.getCause().printStackTrace(); + } + } catch (TosServerException e) { + // 操作失败,捕获服务端异常,可以获取到从服务端返回的详细错误信息 + System.out.println("putObject failed"); + System.out.println("StatusCode: " + e.getStatusCode()); + System.out.println("Code: " + e.getCode()); + System.out.println("Message: " + e.getMessage()); + System.out.println("RequestID: " + e.getRequestID()); + } catch (Throwable t) { + // 作为兜底捕获其他异常,一般不会执行到这里 + System.out.println("putObject failed"); + System.out.println("unexpected exception, message: " + t.getMessage()); + } + return false; + } + + /** + * 上传文件 到 云存储 + * + * @param fileName + * @param fileStream + * @return + */ + public static String saveFileToBucket(String fileName, InputStream fileStream) { + String resultUrl = null; + try { + boolean saveResult = saveByteDanceTos(fileName, fileStream); + if(saveResult){ + resultUrl = "https://hairstyle.tos-accelerate.volces.com/"+bucketPath+fileName; + } + } catch (Exception e) { + e.printStackTrace(); + } + return resultUrl; + } + +} diff --git a/digital-application/src/main/java/digital/application/utils/CommonUtils.java b/digital-application/src/main/java/digital/application/utils/CommonUtils.java new file mode 100644 index 0000000..93fcade --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/CommonUtils.java @@ -0,0 +1,41 @@ +package digital.application.utils; + +public class CommonUtils { + + public static boolean isChineseMobileNumber(String number) { + // 正则表达式判断手机号格式 + String regex = "^1[3-9]\\d{9}$"; + return number.matches(regex); + } + + /** + * 检查路径是否以target结尾,如果不以target结尾,则替换最后一个'/'后的部分为target + * + * @param path + * @param target + * @return + */ + public static String checkAndReplaceLastSegment(String path, String target) { + // 找到最后一个'/'的位置 + int lastIndex = path.lastIndexOf('/'); + if (lastIndex == -1) { + // 如果没有'/',则直接返回原字符串或进行其他处理 + return path; + } + // 截取最后一个'/'之后的部分 + String lastSegment = path.substring(lastIndex + 1); + // 判断截取的部分是否与target相等 + if (!lastSegment.equals(target)) { + // 如果不相等,则构建新的路径,用target替换截取的部分 + return lastSegment; + } + // 如果相等,则返回原路径 + return lastSegment; + } + + public static void main(String[] args) { + String originalPath = "/mnt/database2/online-server/cloth-v2-online/material_path/1813824941203513345"; + String modifiedPath = checkAndReplaceLastSegment(originalPath, "1813824941203513345"); + System.out.println(modifiedPath); + } +} diff --git a/digital-application/src/main/java/digital/application/utils/FileUtils.java b/digital-application/src/main/java/digital/application/utils/FileUtils.java new file mode 100644 index 0000000..2005570 --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/FileUtils.java @@ -0,0 +1,57 @@ +package digital.application.utils; + +import java.io.*; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLConnection; + +public class FileUtils { + + public static void downloadImage(String imageUrl, String localFilePath) throws IOException { + URL url = new URL(imageUrl); + URLConnection connection = url.openConnection(); + InputStream inputStream = new BufferedInputStream(connection.getInputStream()); + + try (OutputStream outputStream = new FileOutputStream(localFilePath)) { + byte[] buffer = new byte[4096]; + int bytesRead; + while ((bytesRead = inputStream.read(buffer)) != -1) { + outputStream.write(buffer, 0, bytesRead); + } + } finally { + inputStream.close(); + } + } + + public static String getObjectNameFromUrl(URL url) { + String path = url.getPath(); + if (path != null && !path.isEmpty()) { + int lastIndex = path.lastIndexOf('/'); + if (lastIndex != -1) { + return path.substring(lastIndex + 1); + } else { + return path; + } + } + return null; + } + + public static String getExtensionFromObjectName(String objectName) { + if (objectName != null && !objectName.isEmpty()) { + int lastIndex = objectName.lastIndexOf('.'); + if (lastIndex != -1 && lastIndex < objectName.length() - 1) { + return objectName.substring(lastIndex + 1); + } + } + return null; + } + + public static long getObjectSizeFromUrl(URL url) throws IOException { + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("HEAD"); + connection.connect(); + long contentLength = connection.getContentLengthLong(); + connection.disconnect(); + return contentLength; + } +} diff --git a/digital-application/src/main/java/digital/application/utils/ImageUtils.java b/digital-application/src/main/java/digital/application/utils/ImageUtils.java new file mode 100644 index 0000000..b2027b1 --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/ImageUtils.java @@ -0,0 +1,64 @@ +package digital.application.utils; + +import java.io.File; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + + +public class ImageUtils { + public static List uploadImagesInFolder(String folderPath) { + List list = new ArrayList<>(); + File folder = new File(folderPath); + File[] files = folder.listFiles(); + if (files != null) { + for (File file : files) { + if (file.isDirectory()) { + // 递归处理子文件夹 + uploadImagesInFolder(file.getAbsolutePath()); + } else { + // 上传图片文件到 OSS + if (isImageFile(file.getName())) { + list.add(file.getAbsolutePath()); + } + } + } + } + return list; + } + + private static boolean isImageFile(String fileName) { + String[] imageExtensions = {"jpg", "jpeg", "png", "gif", "bmp"}; // 可能的图片文件扩展名 + for (String extension : imageExtensions) { + if (fileName.toLowerCase().endsWith(extension)) { + return true; + } + } + return false; + } + + + public static boolean isImageAccessible(String urlString) { + try { + URL url = new URL(urlString); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(3000); + connection.setReadTimeout(3000); + int responseCode = connection.getResponseCode(); + // Check if the response code is 200 (OK) and the content type is an image + return (200 <= responseCode && responseCode < 300) && + connection.getContentType().startsWith("image/"); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + public static void main(String[] args) { + String urlString = "https://copyright.bdstatic.com/vcg/creative/cc9c744cf9f7c864889c563cbdeddce6.jpg"; + boolean isImageAccessible = isImageAccessible(urlString); + System.out.println("Is the URL a accessible image? " + isImageAccessible); + } +} diff --git a/digital-application/src/main/java/digital/application/utils/LiveUtils.java b/digital-application/src/main/java/digital/application/utils/LiveUtils.java new file mode 100644 index 0000000..defc867 --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/LiveUtils.java @@ -0,0 +1,61 @@ +package digital.application.utils; + +import java.io.UnsupportedEncodingException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +public class LiveUtils { + public static void main(String[] args) { +// System.out.println(getSafeUrl("live.aicloud.fit", "digital-person-5619", System.currentTimeMillis())); + } + + private static final char[] DIGITS_LOWER = + {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; + /* + * KEY+ streamName + txTime + */ + public static String getSafeUrl(String key, String streamName, long txTime) { + String input = new StringBuilder(). + append(key). + append(streamName). + append(Long.toHexString(txTime).toUpperCase()).toString(); + + + String txSecret = null; + try { + MessageDigest messageDigest = MessageDigest.getInstance("MD5"); + txSecret = byteArrayToHexString( + messageDigest.digest(input.getBytes("UTF-8"))); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + + return txSecret == null ? "" : + new StringBuilder(). + append("txSecret="). + append(txSecret). + append("&"). + append("txTime="). + append(Long.toHexString(txTime).toUpperCase()). + toString(); + } + + + public static String byteArrayToHexString(byte[] data) { + char[] out = new char[data.length << 1]; + + + for (int i = 0, j = 0; i < data.length; i++) { + out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4]; + out[j++] = DIGITS_LOWER[0x0F & data[i]]; + } + return new String(out); + } + +} diff --git a/digital-application/src/main/java/digital/application/utils/TencentCloudApiUtils.java b/digital-application/src/main/java/digital/application/utils/TencentCloudApiUtils.java new file mode 100644 index 0000000..e1db98f --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/TencentCloudApiUtils.java @@ -0,0 +1,84 @@ +package digital.application.utils; + +import com.tencentcloudapi.asr.v20190614.AsrClient; +import com.tencentcloudapi.asr.v20190614.models.CreateRecTaskRequest; +import com.tencentcloudapi.asr.v20190614.models.CreateRecTaskResponse; +import com.tencentcloudapi.asr.v20190614.models.DescribeTaskStatusRequest; +import com.tencentcloudapi.asr.v20190614.models.DescribeTaskStatusResponse; +import com.tencentcloudapi.common.Credential; +import com.tencentcloudapi.common.exception.TencentCloudSDKException; +import com.tencentcloudapi.common.profile.ClientProfile; +import com.tencentcloudapi.common.profile.HttpProfile; +import lombok.extern.slf4j.Slf4j; + +/** + * 腾讯云 api + */ +@Slf4j +public class TencentCloudApiUtils { + + public static CreateRecTaskResponse CreateRecTask(String url) { + try { + // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密 + // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥, + //请参见:https://cloud.tencent.com/document/product/1278/85305 + // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 + Credential cred = new Credential("AKID2DHE0d7Xt8HHBsSuDRZXMK4gIm8LPNCu", "nS6at34xkQvGUcKtLj3B6qcJwSxKk8Ox"); + // 实例化一个http选项,可选的,没有特殊需求可以跳过 + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("asr.tencentcloudapi.com"); + // 实例化一个client选项,可选的,没有特殊需求可以跳过 + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + // 实例化要请求产品的client对象,clientProfile是可选的 + AsrClient client = new AsrClient(cred, "", clientProfile); + // 实例化一个请求对象,每个接口都会对应一个request对象 + CreateRecTaskRequest req = new CreateRecTaskRequest(); + req.setEngineModelType("16k_zh"); + req.setChannelNum(1L); + req.setResTextFormat(0L); + req.setSourceType(312L); + req.setSourceType(0L); + req.setUrl(url); + // 返回的resp是一个CreateRecTaskResponse的实例,与请求对象对应 + CreateRecTaskResponse resp = client.CreateRecTask(req); + // 输出json格式的字符串回包 +// log.info("输出json格式的字符串回包="+CreateRecTaskResponse.toJsonString(resp)); + return resp; + } catch (TencentCloudSDKException e) { + log.info("方法异常="+e.toString()); + } + return null; + } + + + public static DescribeTaskStatusResponse describeTaskStatus(Long taskId) { + try { + // 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密 + // 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305 + // 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取 + Credential cred = new Credential("AKID2DHE0d7Xt8HHBsSuDRZXMK4gIm8LPNCu", "nS6at34xkQvGUcKtLj3B6qcJwSxKk8Ox"); + // 实例化一个http选项,可选的,没有特殊需求可以跳过 + HttpProfile httpProfile = new HttpProfile(); + httpProfile.setEndpoint("asr.ap-beijing.tencentcloudapi.com"); + // 实例化一个client选项,可选的,没有特殊需求可以跳过 + ClientProfile clientProfile = new ClientProfile(); + clientProfile.setHttpProfile(httpProfile); + // 实例化要请求产品的client对象,clientProfile是可选的 + AsrClient client = new AsrClient(cred, "ap-guangzhou", clientProfile); + // 实例化一个请求对象,每个接口都会对应一个request对象 + DescribeTaskStatusRequest req = new DescribeTaskStatusRequest(); + req.setTaskId(taskId); + // 返回的resp是一个DescribeTaskStatusResponse的实例,与请求对象对应 + DescribeTaskStatusResponse resp = client.DescribeTaskStatus(req); + // 输出json格式的字符串回包 +// log.info("describeTaskStatus="+DescribeTaskStatusResponse.toJsonString(resp)); + return resp; + } catch (TencentCloudSDKException e) { + log.info("方法异常="+e.toString()); + } + return null; + } + + +} diff --git a/digital-application/src/main/java/digital/application/utils/TimeUtils.java b/digital-application/src/main/java/digital/application/utils/TimeUtils.java new file mode 100644 index 0000000..1743bae --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/TimeUtils.java @@ -0,0 +1,78 @@ +package digital.application.utils; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +public class TimeUtils { + + public static boolean compareHour(Date createTime) { + // 获取当前时间 + Date currentTime = new Date(); + // 计算时间差,单位为毫秒 + long diffInMillies = Math.abs(currentTime.getTime() - createTime.getTime()); + // 1小时的毫秒数 3600000; // 60 * 60 * 1000 + long oneHourInMillis = 86400000; // 1天的毫秒数 86400000; // 24 * 60 * 60 * 1000 + // 判断时间差是否超过1个小时 + return diffInMillies > oneHourInMillis; + } + + + /** + * 获取当前时间的UTC格式时间。 + * + * @return 当前时间的UTC格式时间 + */ + public static String getCurrentUtcTime() { + // 获取当前时间的UTC时间戳 + Instant currentInstant = Instant.now(); + // 将时间戳转换为UTC时区的ZonedDateTime对象 + ZonedDateTime currentUtcZonedDateTime = currentInstant.atZone(ZoneId.of("UTC")); + // 格式化输出 + return currentUtcZonedDateTime.format(java.time.format.DateTimeFormatter.ISO_DATE_TIME); + } + + /** + * 获取2天后的UTC格式时间。 String + * + * @return + */ + public static String getTwoDayLaterStringUtcTime() { + // 获取当前时间的UTC时间戳 + Instant currentInstant = Instant.now(); + // 将时间戳转换为UTC时区的ZonedDateTime对象 + ZonedDateTime currentUtcZonedDateTime = currentInstant.atZone(ZoneId.of("UTC")); + // 添加一天的时间 + ZonedDateTime oneDayLaterUtcZonedDateTime = currentUtcZonedDateTime.plus(6, ChronoUnit.DAYS); + // 格式化输出 + return oneDayLaterUtcZonedDateTime.format(java.time.format.DateTimeFormatter.ISO_DATE_TIME); + } + + /** + * 获取2天后的UTC格式时间 long。 + * + * @return + */ + public static long getTwoDayLaterLongUtcTime() { + // 获取当前的UTC时间 + Instant now = Instant.now(); + // 在当前时间上增加两天 + Instant future = now.plus(2, ChronoUnit.DAYS); + + // 转换为自1970年1月1日以来的毫秒数 + long futureMillis = future.toEpochMilli(); + return futureMillis; + } + + public static void main(String[] args) { + // 获取当前时间的UTC格式时间 + String currentUtcTime = TimeUtils.getCurrentUtcTime(); + System.out.println("当前时间的UTC格式时间: " + currentUtcTime); + + // 获取一天后的UTC格式时间 + String oneDayLaterUtcTime = TimeUtils.getTwoDayLaterStringUtcTime(); + System.out.println("一天后的UTC格式时间: " + oneDayLaterUtcTime); + } +} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/utils/VideoUtil.java b/digital-application/src/main/java/digital/application/utils/VideoUtil.java new file mode 100644 index 0000000..85942b2 --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/VideoUtil.java @@ -0,0 +1,78 @@ +package digital.application.utils; + +import com.coremedia.iso.IsoFile; + +import java.io.IOException; +public class VideoUtil { + + /** + * 获取视频文件的播放长度(mp4、mov格式) + * @param videoPath + * @return 单位为毫秒 + */ + public static long getMp4Duration(String videoPath) throws IOException { + IsoFile isoFile = new IsoFile(videoPath); + long lengthInSeconds = + isoFile.getMovieBox().getMovieHeaderBox().getDuration() / + isoFile.getMovieBox().getMovieHeaderBox().getTimescale(); + return lengthInSeconds; + } + + + /** + * 得到语音或视频文件时长,单位秒 + * @param filePath + * @return + * @throws IOException + */ + public static long getDuration(String filePath) throws IOException { + String format = getVideoFormat(filePath); + long result = 0; + if("wav".equals(format)){ + result = AudioUtil.getDuration(filePath).intValue(); + }else if("mp3".equals(format)){ + result = AudioUtil.getMp3Duration(filePath).intValue(); + }else if("m4a".equals(format)) { + result = VideoUtil.getMp4Duration(filePath); + }else if("mov".equals(format)){ + result = VideoUtil.getMp4Duration(filePath); + }else if("mp4".equals(format)){ + result = VideoUtil.getMp4Duration(filePath); + } + + return result; + } + + /** + * 得到语音或视频文件时长,单位秒 + * @param filePath + * @return + * @throws IOException + */ + public static long getDuration(String filePath,String format) throws IOException { + long result = 0; + if("wav".equals(format)){ + result = AudioUtil.getDuration(filePath).intValue(); + }else if("mp3".equals(format)){ + result = AudioUtil.getMp3Duration(filePath).intValue(); + }else if("m4a".equals(format)) { + result = VideoUtil.getMp4Duration(filePath); + }else if("mov".equals(format)){ + result = VideoUtil.getMp4Duration(filePath); + }else if("mp4".equals(format)){ + result = VideoUtil.getMp4Duration(filePath); + } + + return result; + } + + + /** + * 得到文件格式 + * @param path + * @return + */ + public static String getVideoFormat(String path){ + return path.toLowerCase().substring(path.toLowerCase().lastIndexOf(".") + 1); + } +} diff --git a/digital-application/src/main/java/digital/application/utils/WebConfig.java b/digital-application/src/main/java/digital/application/utils/WebConfig.java new file mode 100644 index 0000000..128175b --- /dev/null +++ b/digital-application/src/main/java/digital/application/utils/WebConfig.java @@ -0,0 +1,30 @@ +//package digital.application.utils; +// +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +// +///** +// * 拦截器, 接口需要传输appkey 和appsecret +// */ +//@Configuration +//public class WebConfig implements WebMvcConfigurer { +// +// public static String[] SIGN_URL_LIST = new String[] +// {"/login", "/doc.html", "/*/home", "/error", "/druid/**", "/swagger-ui.html", "/api/common/**", +// "/swagger**/**", "/webjars/**", "/v2/**", +// "/api/digital/custom_callback","/api/video/create_video_callback", +// "/**/*.js", "/**/*.css", "/swagger-resources", +// "/**/*.html", "/**/*.svg", "/**/*.pdf", "/**/*.jpg", "/**/*.png", "/**/*.ico", "/api-docs", +// "/", "/**/*.html"}; +// @Autowired +// private AuthInterceptor authInterceptor; +// +// @Override +// public void addInterceptors(InterceptorRegistry registry) { +// registry.addInterceptor(authInterceptor) +// .addPathPatterns("/**") // 拦截所有路径,可以根据需要调整 +// .excludePathPatterns(SIGN_URL_LIST); // 排除不需要拦截的路径 +// } +//} \ No newline at end of file diff --git a/digital-application/src/main/java/digital/application/vo/CrawlerPictureVO.java b/digital-application/src/main/java/digital/application/vo/CrawlerPictureVO.java new file mode 100644 index 0000000..90756f7 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/CrawlerPictureVO.java @@ -0,0 +1,17 @@ +package digital.application.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class CrawlerPictureVO { + + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; +} diff --git a/digital-application/src/main/java/digital/application/vo/GetModelListVO.java b/digital-application/src/main/java/digital/application/vo/GetModelListVO.java new file mode 100644 index 0000000..4c62c0d --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/GetModelListVO.java @@ -0,0 +1,18 @@ +package digital.application.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class GetModelListVO { + + + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; +} diff --git a/digital-application/src/main/java/digital/application/vo/GetRoomListVO.java b/digital-application/src/main/java/digital/application/vo/GetRoomListVO.java new file mode 100644 index 0000000..2b9e23d --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/GetRoomListVO.java @@ -0,0 +1,26 @@ +package digital.application.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@Data +public class GetRoomListVO { + + @ApiModelProperty(value = "专题试衣间名称id") + private String roomId; + + @ApiModelProperty(value = "专题试衣间名称") + private String roomName; + + @ApiModelProperty(value = "性别") + private String sex; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; +} diff --git a/digital-application/src/main/java/digital/application/vo/GetSwapHairHistoryVO.java b/digital-application/src/main/java/digital/application/vo/GetSwapHairHistoryVO.java new file mode 100644 index 0000000..913165a --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/GetSwapHairHistoryVO.java @@ -0,0 +1,23 @@ +package digital.application.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +@Data +public class GetSwapHairHistoryVO { + + private String historyId; + + private String url; + + private String taskId; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; +} diff --git a/digital-application/src/main/java/digital/application/vo/GetTryOnHistoryVO.java b/digital-application/src/main/java/digital/application/vo/GetTryOnHistoryVO.java new file mode 100644 index 0000000..edb4449 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/GetTryOnHistoryVO.java @@ -0,0 +1,32 @@ +package digital.application.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; +import java.util.List; + +@Data +public class GetTryOnHistoryVO { + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; + + private List clothList; + + @Data + public static class ClothVO { + + private String historyId; + + private String url; + + private String taskId; + + } +} + diff --git a/digital-application/src/main/java/digital/application/vo/GetUploadBackgroundListVO.java b/digital-application/src/main/java/digital/application/vo/GetUploadBackgroundListVO.java new file mode 100644 index 0000000..9e33c7e --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/GetUploadBackgroundListVO.java @@ -0,0 +1,18 @@ +package digital.application.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class GetUploadBackgroundListVO { + + @ApiModelProperty(value = "背景图Id") + private Integer backgroundId; + + @ApiModelProperty(value = "VERTICAL,横竖屏 VERTICAL:竖版 HORIZONTAL横版") + private String align; + + @ApiModelProperty(value = "url ") + private String url ; + +} diff --git a/digital-application/src/main/java/digital/application/vo/LoginUserInfoVO.java b/digital-application/src/main/java/digital/application/vo/LoginUserInfoVO.java new file mode 100644 index 0000000..d5ef348 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/LoginUserInfoVO.java @@ -0,0 +1,31 @@ +package digital.application.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class LoginUserInfoVO { + + private String id; + + @ApiModelProperty(value = "姓名") + private String username; + + @ApiModelProperty(value = "角色") + private String roleType; + + @ApiModelProperty(value = "剩下使用次数") + private BigDecimal remainNum; + + @ApiModelProperty(value = "登录人名字") + private String realname; + + @ApiModelProperty(value = "头像") + private String avatar; + + private Date createTime; + +} diff --git a/digital-application/src/main/java/digital/application/vo/QueryClothTypeListVO.java b/digital-application/src/main/java/digital/application/vo/QueryClothTypeListVO.java new file mode 100644 index 0000000..373d240 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/QueryClothTypeListVO.java @@ -0,0 +1,31 @@ +package digital.application.vo; + + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class QueryClothTypeListVO { + + @ApiModelProperty(value = "文件状态 enable : 启用 disable :禁用") + private String fileStatus; + + @ApiModelProperty(value = "衣服类型") + private String clothType; + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; + + @ApiModelProperty(value = "文件id") + private String clothId; + + @ApiModelProperty(value = "是否拥有") + private String isHas; + + @ApiModelProperty(value = "购买链接") + private String buyLink; + +} diff --git a/digital-application/src/main/java/digital/application/vo/StartDetailVO.java b/digital-application/src/main/java/digital/application/vo/StartDetailVO.java new file mode 100644 index 0000000..e9fbd77 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/StartDetailVO.java @@ -0,0 +1,23 @@ +package digital.application.vo; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class StartDetailVO { + + @ApiModelProperty(value = "拉流地址") + private String pullUrl; + +// @ApiModelProperty(value = "RTS拉流地址") +// private String rtsUrl; + + @ApiModelProperty(value = "前后端以及算法交互的sessionId") + private String sessionId; + + @ApiModelProperty(value = "状态") + private String status; + + @ApiModelProperty(value = "结果说明") + private String resultMsg; +} diff --git a/digital-application/src/main/java/digital/application/vo/UploadFileClothVO.java b/digital-application/src/main/java/digital/application/vo/UploadFileClothVO.java new file mode 100644 index 0000000..821ffbf --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/UploadFileClothVO.java @@ -0,0 +1,18 @@ +package digital.application.vo; + + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class UploadFileClothVO { + + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; +} diff --git a/digital-application/src/main/java/digital/application/vo/tjHair/TjHairListVO.java b/digital-application/src/main/java/digital/application/vo/tjHair/TjHairListVO.java new file mode 100644 index 0000000..a10b885 --- /dev/null +++ b/digital-application/src/main/java/digital/application/vo/tjHair/TjHairListVO.java @@ -0,0 +1,18 @@ +package digital.application.vo.tjHair; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +public class TjHairListVO { + + @ApiModelProperty(value = "访问地址") + private String fileUrl; + + @ApiModelProperty(value = "缩略图访问地址") + private String thumbnailFileUrl; + + @ApiModelProperty(value = "文件id") + private String fileId; + +} diff --git a/digital-application/src/main/resources/application-dev.yml b/digital-application/src/main/resources/application-dev.yml new file mode 100644 index 0000000..d795317 --- /dev/null +++ b/digital-application/src/main/resources/application-dev.yml @@ -0,0 +1,216 @@ +server: + port: 9540 + tomcat: + max-swallow-size: -1 + error: + include-exception: true + include-stacktrace: ALWAYS + include-message: ALWAYS + servlet: + context-path: + compression: + enabled: true + min-response-size: 1024 + mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/* + +#LOG_SERVICE_NAME: gjf-face3d-prod-neiwang33 +#LOG_STASH_DESTINATION: 172.16.16.39:50000 + +#图片落盘地址 +cloth: + uploaded_folder: D:\大妈\数字人 + +management: + endpoints: + web: + exposure: + include: metrics,httptrace + +spring: + main: + allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册 + servlet: + multipart: + max-file-size: 2000MB + max-request-size: 2000MB + #json 时间戳统一转换 + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + jpa: + open-in-view: false + activiti: + check-process-definitions: false + #启用作业执行器 + async-executor-activate: false + #启用异步执行器 + job-executor-activate: false + aop: + proxy-target-class: true + #配置freemarker + freemarker: + # 设置模板后缀名 + suffix: .ftl + # 设置文档类型 + content-type: text/html + # 设置页面编码格式 + charset: UTF-8 + # 设置页面缓存 + cache: false + prefer-file-system-access: false + # 设置ftl文件路径 + template-loader-path: + - classpath:/templates + # 设置静态文件路径,js,css等 + mvc: + static-path-pattern: /** + #Spring Boot 2.6+后映射匹配的默认策略已从AntPathMatcher更改为PathPatternParser,需要手动指定为ant-path-matcher + pathmatch: + matching-strategy: ant_path_matcher + resource: + static-locations: classpath:/static/,classpath:/public/ + autoconfigure: + exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + datasource: + druid: + stat-view-servlet: + enabled: true + loginUsername: admin + loginPassword: 123456 + allow: + web-stat-filter: + enabled: true + dynamic: + druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置) + # 连接池的配置信息 + # 初始化大小,最小,最大 + initial-size: 5 + min-idle: 5 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + # 打开PSCache,并且指定每个连接上PSCache的大小 + poolPreparedStatements: true + maxPoolPreparedStatementPerConnectionSize: 20 + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + filters: stat,wall,slf4j + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 + datasource: + master: + url: jdbc:mysql://rm-bp10023cg2xmmpasaio.mysql.rds.aliyuncs.com:3306/digital_cloth_v2?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + username: szlc + password: Tj1994923 + driver-class-name: com.mysql.cj.jdbc.Driver + db_user_mysql: + url: jdbc:mysql://rm-bp10023cg2xmmpasaio.mysql.rds.aliyuncs.com:3306/digital_unify?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + username: szlc + password: Tj1994923 + driver-class-name: com.mysql.cj.jdbc.Driver + #redis 配置 + redis: + database: 0 + host: service.aicloud.fit + lettuce: + pool: + max-active: 8 #最大连接数据库连接数,设 -1 为没有限制 + max-idle: 8 #最大等待连接中的数量,设 0 为没有限制 + max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 + min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 + shutdown-timeout: 100ms + password: 'cloth_swap' + port: 9093 +# port:9093 6379退出登录成功 +#mybatis plus 设置 +mybatis-plus: + mapper-locations: classpath*:digital/**/xml/*Mapper.xml + global-config: + # 关闭MP3.0自带的banner + banner: false + db-config: + #主键类型 0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)"; + id-type: ASSIGN_ID + # 默认数据库表下划线命名 + table-underline: true + configuration: + # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 + #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # 返回类型为Map,显示null对应的字段 + call-setters-on-nulls: true +#jeecg专用配置 +#minidao: +# base-package: org.jeecg.modules.jmreport.* +jeecg: + # 是否启用安全模式 + safeMode: false + # 签名密钥串(前后端要一致,正式发布请自行修改) + signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a + # 本地:local\Minio:minio\阿里云:alioss + uploadType: alioss + path: + #文件上传根目录 设置 + upload: /opt/upFiles + #webapp文件路径 + webapp: /opt/webapp + shiro: + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/file/doCallBackOss + # 在线预览文件服务器地址配置 + file-view-domain: 127.0.0.1:8012 + oss: + endpoint: oss-cn-beijing.aliyuncs.com + accessKey: LTAI5tMq9DivPYYkcpc6qhNP + secretKey: XIkDAq7r4U9BVf7fkKECP46FXDLF9l + bucketName: digit-person + staticDomain: https://digit-person.oss-cn-beijing.aliyuncs.com + #Wps在线文档 + wps: + domain: https://wwo.wps.cn/office/ + appid: ?? + appsecret: ?? + route: + config: + data-id: jeecg-gateway-router + group: DEFAULT_GROUP + #自定义路由配置 yml nacos database + data-type: database +#Mybatis输出sql日志 +logging: + level: + digital: + application: + mapper: debug +# system: +# jeecg: +# group: +# base: +# mapper: debug +# system: +# mapper: debug +# base: +# mapper: debug +#swagger +springfox: + documentation: + swagger: + use-model-v3: false +knife4j: + #开启增强配置 + enable: true + #开启生产环境屏蔽 + production: false + basic: + enable: false + username: digital + password: 123 +encrypt: + body: + aes-key: 46EBA22EF5204DD5B110A1F730513965 #AES加密秘钥 + des-key: 46EBA22EF5204DD5B110A1F730513965 #DES加密秘钥 diff --git a/digital-application/src/main/resources/application-prod.yml b/digital-application/src/main/resources/application-prod.yml new file mode 100644 index 0000000..236c0a7 --- /dev/null +++ b/digital-application/src/main/resources/application-prod.yml @@ -0,0 +1,216 @@ +server: + port: 9281 + tomcat: + max-swallow-size: -1 + error: + include-exception: true + include-stacktrace: ALWAYS + include-message: ALWAYS + servlet: + context-path: + compression: + enabled: true + min-response-size: 1024 + mime-types: application/javascript,application/json,application/xml,text/html,text/xml,text/plain,text/css,image/* + +#LOG_SERVICE_NAME: gjf-face3d-prod-neiwang33 +#LOG_STASH_DESTINATION: 172.16.16.39:50000 + +#图片落盘地址 +cloth: + uploaded_folder: /mnt/database2/online-server/cloth-v2-online +# uploaded_folder: /mnt/database2/cloth-v2-online +management: + endpoints: + web: + exposure: + include: metrics,httptrace + +spring: + main: + allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册 + servlet: + multipart: + max-file-size: 2000MB + max-request-size: 2000MB + #json 时间戳统一转换 + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + jpa: + open-in-view: false + activiti: + check-process-definitions: false + #启用作业执行器 + async-executor-activate: false + #启用异步执行器 + job-executor-activate: false + aop: + proxy-target-class: true + #配置freemarker + freemarker: + # 设置模板后缀名 + suffix: .ftl + # 设置文档类型 + content-type: text/html + # 设置页面编码格式 + charset: UTF-8 + # 设置页面缓存 + cache: false + prefer-file-system-access: false + # 设置ftl文件路径 + template-loader-path: + - classpath:/templates + # 设置静态文件路径,js,css等 + mvc: + static-path-pattern: /** + #Spring Boot 2.6+后映射匹配的默认策略已从AntPathMatcher更改为PathPatternParser,需要手动指定为ant-path-matcher + pathmatch: + matching-strategy: ant_path_matcher + resource: + static-locations: classpath:/static/,classpath:/public/ + autoconfigure: + exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure + datasource: + druid: + stat-view-servlet: + enabled: true + loginUsername: admin + loginPassword: 123456 + allow: + web-stat-filter: + enabled: true + dynamic: + druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置) + # 连接池的配置信息 + # 初始化大小,最小,最大 + initial-size: 5 + min-idle: 5 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + validationQuery: SELECT 1 + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + # 打开PSCache,并且指定每个连接上PSCache的大小 + poolPreparedStatements: true + maxPoolPreparedStatementPerConnectionSize: 20 + # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙 + filters: stat,wall,slf4j + # 通过connectProperties属性来打开mergeSql功能;慢SQL记录 + connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000 + datasource: + master: + url: jdbc:mysql://rm-bp10023cg2xmmpasaio.mysql.rds.aliyuncs.com:3306/digital_cloth_v2?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + username: szlc + password: Tj1994923 + driver-class-name: com.mysql.cj.jdbc.Driver + db_user_mysql: + url: jdbc:mysql://rm-bp10023cg2xmmpasaio.mysql.rds.aliyuncs.com:3306/digital_unify?characterEncoding=UTF-8&useUnicode=true&useSSL=false&tinyInt1isBit=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai + username: szlc + password: Tj1994923 + driver-class-name: com.mysql.cj.jdbc.Driver + #redis 配置 + redis: + database: 0 + host: 127.0.0.1 + lettuce: + pool: + max-active: 8 #最大连接数据库连接数,设 -1 为没有限制 + max-idle: 8 #最大等待连接中的数量,设 0 为没有限制 + max-wait: -1ms #最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制。 + min-idle: 0 #最小等待连接中的数量,设 0 为没有限制 + shutdown-timeout: 100ms + password: 'cloth_swap' + port: 9093 +# port:9093 6379退出登录成功 +#mybatis plus 设置 +mybatis-plus: + mapper-locations: classpath*:digital/**/xml/*Mapper.xml + global-config: + # 关闭MP3.0自带的banner + banner: false + db-config: + #主键类型 0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)"; + id-type: ASSIGN_ID + # 默认数据库表下划线命名 + table-underline: true + configuration: + # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 + #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # 返回类型为Map,显示null对应的字段 + call-setters-on-nulls: true +#jeecg专用配置 +#minidao: +# base-package: org.jeecg.modules.jmreport.* +jeecg: + # 是否启用安全模式 + safeMode: false + # 签名密钥串(前后端要一致,正式发布请自行修改) + signatureSecret: dd05f1c54d63749eda95f9fa6d49v442a + # 本地:local\Minio:minio\阿里云:alioss + uploadType: alioss + path: + #文件上传根目录 设置 + upload: /opt/upFiles + #webapp文件路径 + webapp: /opt/webapp + shiro: + excludeUrls: /test/jeecgDemo/demo3,/test/jeecgDemo/redisDemo/**,/category/**,/visual/**,/map/**,/jmreport/bigscreen2/**,/file/doCallBackOss + # 在线预览文件服务器地址配置 + file-view-domain: 127.0.0.1:8012 + oss: + endpoint: oss-cn-beijing.aliyuncs.com + accessKey: LTAI5tMq9DivPYYkcpc6qhNP + secretKey: XIkDAq7r4U9BVf7fkKECP46FXDLF9l + bucketName: digit-person + staticDomain: https://digit-person.oss-cn-beijing.aliyuncs.com + #Wps在线文档 + wps: + domain: https://wwo.wps.cn/office/ + appid: ?? + appsecret: ?? + route: + config: + data-id: jeecg-gateway-router + group: DEFAULT_GROUP + #自定义路由配置 yml nacos database + data-type: database +#Mybatis输出sql日志 +#logging: +# level: +# digital: +# application: +# mapper: debug +# system: +# jeecg: +# group: +# base: +# mapper: debug +# system: +# mapper: debug +# base: +# mapper: debug +#swagger +springfox: + documentation: + swagger: + use-model-v3: false +knife4j: + #开启增强配置 + enable: true + #开启生产环境屏蔽 + production: false + basic: + enable: false + username: digital + password: 123 +encrypt: + body: + aes-key: 46EBA22EF5204DD5B110A1F730513965 #AES加密秘钥 + des-key: 46EBA22EF5204DD5B110A1F730513965 #DES加密秘钥 diff --git a/digital-application/src/main/resources/application.yml b/digital-application/src/main/resources/application.yml new file mode 100644 index 0000000..2ee0e81 --- /dev/null +++ b/digital-application/src/main/resources/application.yml @@ -0,0 +1,5 @@ +spring: + application: + name: digital_cloth + profiles: + active: prod \ No newline at end of file diff --git a/digital-application/src/main/resources/banner.txt b/digital-application/src/main/resources/banner.txt new file mode 100644 index 0000000..f3e9183 --- /dev/null +++ b/digital-application/src/main/resources/banner.txt @@ -0,0 +1,16 @@ +${AnsiColor.BRIGHT_BLUE} + + + .___.__ .__ __ .__ + __| _/|__| ____ |__|/ |______ | | ______ ___________ __________ ____ + / __ | | |/ ___\| \ __\__ \ | | \____ \_/ __ \_ __ \/ ___/ _ \ / \ +/ /_/ | | / /_/ > || | / __ \| |__ | |_> > ___/| | \/\___ ( <_> ) | \ +\____ | |__\___ /|__||__| (____ /____/____| __/ \___ >__| /____ >____/|___| / + \/ /_____/ \/ /_____/__| \/ \/ \/ + + + +${AnsiColor.BRIGHT_GREEN} +Jeecg Boot Version: 3.2.0 +Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} +${AnsiColor.BLACK} diff --git a/digital-application/src/main/resources/logback-spring.xml b/digital-application/src/main/resources/logback-spring.xml new file mode 100644 index 0000000..edc8cee --- /dev/null +++ b/digital-application/src/main/resources/logback-spring.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}:%L) - %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${LOG_HOME}/jeecgboot-%d{yyyy-MM-dd}.%i.log + + 30 + 10MB + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:%L - %msg%n + + + + + + + + ERROR + + + + %p%d%msg%M%F{32}%L + + + ${LOG_HOME}/error-log.html + + + + + + + + ${LOG_HOME}/jeecgboot-%d{yyyy-MM-dd}.%i.html + + 30 + 10MB + + + + %p%d%msg%M%F{32}%L + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-common/digital-base/pom.xml b/digital-common/digital-base/pom.xml new file mode 100644 index 0000000..e40da47 --- /dev/null +++ b/digital-common/digital-base/pom.xml @@ -0,0 +1,63 @@ + + + + digital-common + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-base + + + 8 + 8 + + + + + + org.springframework.boot + spring-boot-starter-web + true + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.apache.commons + commons-pool2 + + + + cn.hutool + hutool-core + + + cn.hutool + hutool-crypto + + + + commons-beanutils + commons-beanutils + + + org.apache.shiro + shiro-core + 1.9.1 + compile + + + io.swagger + swagger-annotations + 1.5.22 + compile + + + + \ No newline at end of file diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/AutoDict.java b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoDict.java new file mode 100644 index 0000000..68a44d6 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoDict.java @@ -0,0 +1,24 @@ +package digital.base.annotation; + +import java.lang.annotation.*; + +/** + * 通过此注解声明的接口,自动实现字典翻译 + * + * @Author scott + * @email jeecgos@163.com + * @Date 2022年01月05日 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AutoDict { + + /** + * 暂时无用 + * + * @return + */ + String value() default ""; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLog.java b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLog.java new file mode 100644 index 0000000..6fc8f5b --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLog.java @@ -0,0 +1,47 @@ +package digital.base.annotation; + +import digital.base.constant.CommonConstant; +import digital.base.enums.ModuleType; + +import java.lang.annotation.*; + +/** + * 系统日志注解 + * + * @Author scott + * @email jeecgos@163.com + * @Date 2019年1月14日 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AutoLog { + + /** + * 日志内容 + * + * @return + */ + String value() default ""; + + /** + * 日志类型 + * + * @return 0:操作日志;1:登录日志;2:定时任务; + */ + int logType() default CommonConstant.LOG_TYPE_2; + + /** + * 操作日志类型 + * + * @return (1查询,2添加,3修改,4删除) + */ + int operateType() default 0; + + /** + * 模块类型 默认为common + * + * @return + */ + ModuleType module() default ModuleType.COMMON; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLowApp.java b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLowApp.java new file mode 100644 index 0000000..b5074a6 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/AutoLowApp.java @@ -0,0 +1,34 @@ +package digital.base.annotation; + +import digital.base.enums.LowAppAopEnum; + +import java.lang.annotation.*; + + +/** + * 自动注入low_app_id + * + * @Author scott + * @email jeecgos@163.com + * @Date 2022年01月05日 + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface AutoLowApp { + + /** + * 切面类型(add、delete、db_import等其他操作) + * + * @return + */ + LowAppAopEnum action(); + + /** + * 业务类型(cgform等) + * + * @return + */ + String bizType(); + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/Dict.java b/digital-common/digital-base/src/main/java/digital/base/annotation/Dict.java new file mode 100644 index 0000000..207efa2 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/Dict.java @@ -0,0 +1,43 @@ +package digital.base.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 字典注解 + * + * @author: dangzhenghui + * @date: 2019年03月17日-下午9:37:16 + */ +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Dict { + /** + * 方法描述: 数据code + * 作 者: dangzhenghui + * 日 期: 2019年03月17日-下午9:37:16 + * + * @return 返回类型: String + */ + String dicCode(); + + /** + * 方法描述: 数据Text + * 作 者: dangzhenghui + * 日 期: 2019年03月17日-下午9:37:16 + * + * @return 返回类型: String + */ + String dicText() default ""; + + /** + * 方法描述: 数据字典表 + * 作 者: dangzhenghui + * 日 期: 2019年03月17日-下午9:37:16 + * + * @return 返回类型: String + */ + String dictTable() default ""; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/OnlineAuth.java b/digital-common/digital-base/src/main/java/digital/base/annotation/OnlineAuth.java new file mode 100644 index 0000000..e5a65f8 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/OnlineAuth.java @@ -0,0 +1,21 @@ +package digital.base.annotation; + +import java.lang.annotation.*; + +/** + * online请求拦截专用注解 + * + * @author: smcp + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Documented +public @interface OnlineAuth { + + /** + * 请求关键字,在xxx/code之前的字符串 + * + * @return + */ + String value(); +} diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/PermissionData.java b/digital-common/digital-base/src/main/java/digital/base/annotation/PermissionData.java new file mode 100644 index 0000000..3b556f0 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/PermissionData.java @@ -0,0 +1,27 @@ +package digital.base.annotation; + +import java.lang.annotation.*; + +/** + * 数据权限注解 + * + * @Author taoyan + * @Date 2019年4月11日 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Documented +public @interface PermissionData { + /** + * 暂时没用 + * + * @return + */ + String value() default ""; + + + /** + * 配置菜单的组件路径,用于数据权限 + */ + String pageComponent() default ""; +} \ No newline at end of file diff --git a/digital-common/digital-base/src/main/java/digital/base/annotation/RabbitComponent.java b/digital-common/digital-base/src/main/java/digital/base/annotation/RabbitComponent.java new file mode 100644 index 0000000..970a496 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/annotation/RabbitComponent.java @@ -0,0 +1,24 @@ +package digital.base.annotation; + + +import org.springframework.core.annotation.AliasFor; +import org.springframework.stereotype.Component; + +import java.lang.annotation.*; + +/** + * @Author:zyf + * @Date:2019-07-31 10:43 + * @Description: 消息队列初始化注解 + **/ +@Documented +@Inherited +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Component +public @interface RabbitComponent { + @AliasFor( + annotation = Component.class + ) + String value(); +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/CacheConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/CacheConstant.java new file mode 100644 index 0000000..2673244 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/CacheConstant.java @@ -0,0 +1,103 @@ +package digital.base.constant; + +/** + * @author: huangxutao + * @date: 2019-06-14 + * @description: 缓存常量 + */ +public interface CacheConstant { + + /** + * 字典信息缓存(含禁用的字典项) + */ + public static final String SYS_DICT_CACHE = "sys:cache:dict"; + + /** + * 字典信息缓存 status为有效的 + */ + public static final String SYS_ENABLE_DICT_CACHE = "sys:cache:dictEnable"; + /** + * 表字典信息缓存 + */ + public static final String SYS_DICT_TABLE_CACHE = "sys:cache:dictTable"; + public static final String SYS_DICT_TABLE_BY_KEYS_CACHE = SYS_DICT_TABLE_CACHE + "ByKeys"; + + /** + * 数据权限配置缓存 + */ + public static final String SYS_DATA_PERMISSIONS_CACHE = "sys:cache:permission:datarules"; + + /** + * 缓存用户信息 + */ + public static final String SYS_USERS_CACHE = "sys:cache:user"; + + /** + * 全部部门信息缓存 + */ + public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata"; + + + /** + * 全部部门ids缓存 + */ + public static final String SYS_DEPART_IDS_CACHE = "sys:cache:depart:allids"; + + + /** + * 测试缓存key + */ + public static final String TEST_DEMO_CACHE = "test:demo"; + + /** + * 字典信息缓存 + */ + public static final String SYS_DYNAMICDB_CACHE = "sys:cache:dbconnect:dynamic:"; + + /** + * gateway路由缓存 + */ + public static final String GATEWAY_ROUTES = "sys:cache:cloud:gateway_routes"; + + + /** + * gateway路由 reload key + */ + public static final String ROUTE_JVM_RELOAD_TOPIC = "gateway_jvm_route_reload_topic"; + + /** + * TODO 冗余代码 待删除 + *插件商城排行榜 + */ + public static final String PLUGIN_MALL_RANKING = "pluginMall::rankingList"; + /** + * TODO 冗余代码 待删除 + *插件商城排行榜 + */ + public static final String PLUGIN_MALL_PAGE_LIST = "pluginMall::queryPageList"; + + + /** + * online列表页配置信息缓存key + */ + public static final String ONLINE_LIST = "sys:cache:online:list"; + + /** + * online表单页配置信息缓存key + */ + public static final String ONLINE_FORM = "sys:cache:online:form"; + + /** + * online报表 + */ + public static final String ONLINE_RP = "sys:cache:online:rp"; + + /** + * online图表 + */ + public static final String ONLINE_GRAPH = "sys:cache:online:graph"; + /** + * 拖拽页面信息缓存 + */ + public static final String DRAG_PAGE_CACHE = "drag:cache:page"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/CommonConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/CommonConstant.java new file mode 100644 index 0000000..fd934c4 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/CommonConstant.java @@ -0,0 +1,391 @@ +package digital.base.constant; + +/** + * @Description: 通用常量 + * @author: smcp + */ +public interface CommonConstant { + + public static final Integer CALLBACK_SUCCESS = 0; + + public static final Integer CALLBACK_FAIL = -1; + + public static final String TRY_ON_TYPE_ALGO_CLOTH = "cloth"; + + public static final String TRY_ON_TYPE_ALGO_HAIR = "hair"; + + public static final String TRY_ON_TYPE_SINGLE = "single"; + + public static final String TRY_ON_TYPE_BATCH = "batch"; + + public static final String ROLE_TYPE_SUPER_ADMIN = "admin"; + + public static final String COMMON_YES = "yes"; + + public static final String COMMON_NO = "no"; + + public static final String EXCLUDE_SUIT = "excludeSuit"; + + public static final String TYPE_TOP_CLOTH = "topCloth"; + + public static final String TYPE_BOTTOM_CLOTH = "bottomCloth"; + + public static final String TYPE_DRESS = "dress"; + + //发型 + public static final String TYPE_HAIR = "hair"; + + //身材 + public static final String TYPE_FIGURE = "figure"; + + //内衣 + public static final String TYPE_UNDERWEAR = "underwear"; + + //试穿 生成中图片链接 + public static final String TRY_ON_IN_PROCESS = "https://digit-person.oss-cn-beijing.aliyuncs.com/digital_cloth/1720084773937.png"; + //试穿 生成失败图片链接 + public static final String TRY_ON_FAIL = "https://digit-person.oss-cn-beijing.aliyuncs.com/digital_cloth/1720084729963.png"; + /** + * 短信验证码redis-key的前缀 + */ + String PHONE_REDIS_KEY_PRE = "phone_msg"; + /** + * 衣服 + */ + public static final String CLOTH_FILE_TYPE = "clothType"; + /** + * 模特 + */ + public static final String MODEL_FILE_TYPE = "modelType"; + + /** + * 发型 + */ + public static final String HAIR_FILE_TYPE = "hairType"; + + /** + * 超级管理员 tenantId 值 + */ + String ADMIN_TENANT_ID = "0"; + + /** + * 数字人审核 成功! 1 合格 0不 合格 + */ + public static final Integer CUSTOM_CHECK_SUCCESS = 1; + /** + * 视频是否合格 1 合格 0不 合格 + */ + public static final Integer VIDEO_CHECK_FAIL = 0; + /** + * 竖版 + */ + public static final String picture_align_type_VERTICAL = "VERTICAL"; + + /** + * :横版 + */ + public static final String picture_align_type_HORIZONTAL = "HORIZONTAL"; + + /** + * 上传视频管理 前缀 + */ + public static final String FILE_VIRTUAL_HUMAN = "virtual_human"; + + public static final String DIGITAL_CLOTH = "digital_cloth"; + + /** + * 文件状态 禁用 + */ + public static final String FILE_STATUS_DISABLE = "disable"; + /** + * 文件状态 失败 + */ + public static final String FILE_STATUS_FAIL = "fail"; + /** + * 文件状态可用 + */ + public static final String FILE_STATUS_ENABLE = "enable"; + /** + * 来源 第三方 + */ + public static final String FILE_TYPE_VIDEO = "video"; + + public static final String PUTON_SWAP = "cloth_swap"; + + public static final String HAIR_SWAP = "hair"; + + public static final String FILE_TYPE_AUDIO = "audio"; + + public static final String FILE_TYPE_PICTURE = "picture"; + /** + * 来源 自研 + */ + public static final String SOURCE_TYPE_SELF_DEVELOP = "0"; + + /** + * 来源 第三方 + */ + public static final String SOURCE_TYPE_THIRD = "1"; + + public static final String CUSTOMIZED_TYPE = "CUSTOMIZED"; + + public static final String FREE_TYPE = "FREE"; + + public static final Integer CUSTOMIZED_TYPE_VALUE = 1; + + public static final Integer FREE_TYPE_VALUE = 2; + + + /** + * 删除标志 + */ + public static final Integer DEL_FLAG_1 = 1; + + /** + * 未删除 + */ + public static final Integer DEL_FLAG_0 = 0; + + + /** + * 系统日志类型: 登录 + */ + public static final int LOG_TYPE_1 = 1; + + /** + * 系统日志类型: 操作 + */ + public static final int LOG_TYPE_2 = 2; + + /** + * 操作日志类型: 查询 + */ + public static final int OPERATE_TYPE_1 = 1; + + /** + * 操作日志类型: 添加 + */ + public static final int OPERATE_TYPE_2 = 2; + + /** + * 操作日志类型: 更新 + */ + public static final int OPERATE_TYPE_3 = 3; + + /** + * 操作日志类型: 删除 + */ + public static final int OPERATE_TYPE_4 = 4; + + /** + * 操作日志类型: 倒入 + */ + public static final int OPERATE_TYPE_5 = 5; + + /** + * 操作日志类型: 导出 + */ + public static final int OPERATE_TYPE_6 = 6; + + + /** + * {@code 500 Server Error} (HTTP/1.0 - RFC 1945) + */ + public static final Integer SC_INTERNAL_SERVER_ERROR_500 = 500; + /** + * {@code 200 OK} (HTTP/1.0 - RFC 1945) + */ + public static final Integer SC_OK_200 = 200; + + /** + * 访问权限认证未通过 510 + */ + public static final Integer SC_JEECG_NO_AUTHZ = 510; + + /** + * 登录用户Shiro权限缓存KEY前缀 + */ + public static String PREFIX_USER_SHIRO_CACHE = "shiro:cache:org.jeecg.config.shiro.ShiroRealm.authorizationCache:"; + /** + * 登录用户Token令牌缓存KEY前缀 + */ + public static final String PREFIX_USER_TOKEN = "prefix_user_token_"; +// /** Token缓存时间:3600秒即一小时 */ +// public static final int TOKEN_EXPIRE_TIME = 3600; + + + /** + * 0:一级菜单 + */ + public static final Integer MENU_TYPE_0 = 0; + /** + * 1:子菜单 + */ + public static final Integer MENU_TYPE_1 = 1; + /** + * 2:按钮权限 + */ + public static final Integer MENU_TYPE_2 = 2; + + /** + * 通告对象类型(USER:指定用户,ALL:全体用户) + */ + public static final String MSG_TYPE_UESR = "USER"; + public static final String MSG_TYPE_ALL = "ALL"; + + /** + * 发布状态(0未发布,1已发布,2已撤销) + */ + public static final String NO_SEND = "0"; + public static final String HAS_SEND = "1"; + public static final String HAS_CANCLE = "2"; + + /** + * 阅读状态(0未读,1已读) + */ + public static final String HAS_READ_FLAG = "1"; + public static final String NO_READ_FLAG = "0"; + + /** + * 优先级(L低,M中,H高) + */ + public static final String PRIORITY_L = "L"; + public static final String PRIORITY_M = "M"; + public static final String PRIORITY_H = "H"; + + /** + * 短信模板方式 0 .登录模板、1.注册模板、2.忘记密码模板 + */ + public static final String SMS_TPL_TYPE_0 = "0"; + public static final String SMS_TPL_TYPE_1 = "1"; + public static final String SMS_TPL_TYPE_2 = "2"; + + /** + * 状态(0无效1有效) + */ + public static final String STATUS_0 = "0"; + public static final String STATUS_1 = "1"; + + /** + * 同步工作流引擎1同步0不同步 + */ + public static final Integer ACT_SYNC_1 = 1; + public static final Integer ACT_SYNC_0 = 0; + + /** + * 消息类型1:通知公告2:系统消息 + */ + public static final String MSG_CATEGORY_1 = "1"; + public static final String MSG_CATEGORY_2 = "2"; + + /** + * 是否配置菜单的数据权限 1是0否 + */ + public static final Integer RULE_FLAG_0 = 0; + public static final Integer RULE_FLAG_1 = 1; + + /** + * 是否用户已被冻结 1正常(解冻) 2冻结 + */ + public static final Integer USER_UNFREEZE = 1; + public static final Integer USER_FREEZE = 2; + + /** + * 字典翻译文本后缀 + */ + public static final String DICT_TEXT_SUFFIX = "_dictText"; + + + /** + * 文件上传类型(本地:local,Minio:minio,阿里云:alioss) + */ + public static final String UPLOAD_TYPE_LOCAL = "local"; + public static final String UPLOAD_TYPE_MINIO = "minio"; + public static final String UPLOAD_TYPE_OSS = "alioss"; + + /** + * sys_quartz_job 表 job_class_name 唯一键索引 + */ + public static final String SQL_INDEX_UNIQ_JOB_CLASS_NAME = "uniq_job_class_name"; + /** + * sys_position 表 code 唯一键索引 + */ + public static final String SQL_INDEX_UNIQ_CODE = "uniq_code"; + /** + * sys_role 表 code 唯一键索引 + */ + public static final String SQL_INDEX_UNIQ_SYS_ROLE_CODE = "uniq_sys_role_role_code"; + /** + * sys_depart 表 code 唯一键索引 + */ + public static final String SQL_INDEX_UNIQ_DEPART_ORG_CODE = "uniq_depart_org_code"; + /** + * sys_category 表 code 唯一键索引 + */ + public static final String SQL_INDEX_UNIQ_CATEGORY_CODE = "idx_sc_code"; + + + public final static String X_ACCESS_TOKEN = "X-Access-Token"; + public final static String X_SIGN = "X-Sign"; + public final static String X_TIMESTAMP = "X-TIMESTAMP"; + public final static String TOKEN_IS_INVALID_MSG = "Token失效,请重新登录!"; + + /** + * 多租户 请求头 + */ + public final static String TENANT_ID = "tenant-id"; + + /** + * 微服务读取配置文件属性 服务地址 + */ + public final static String CLOUD_SERVER_KEY = "spring.cloud.nacos.discovery.server-addr"; + + /** + * 第三方登录 验证密码/创建用户 都需要设置一个操作码 防止被恶意调用 + */ + public final static String THIRD_LOGIN_CODE = "third_login_code"; + + + /** + * ONLINE 报表权限用 从request中获取地址栏后的参数 + */ + String ONL_REP_URL_PARAM_STR = "onlRepUrlParamStr"; + + /** + * POST请求 + */ + String HTTP_POST = "POST"; + + /** + * PUT请求 + */ + String HTTP_PUT = "PUT"; + + /** + * PATCH请求 + */ + String HTTP_PATCH = "PATCH"; + + /** + * 未知的 + */ + String UNKNOWN = "unknown"; + + /** + * 字符串http + */ + String STR_HTTP = "http"; + + /** + * String 类型的空值 + */ + String STRING_NULL = "null"; + + + /** + * .do + */ + String SPOT_DO = ".do"; + + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/CommonSendStatus.java b/digital-common/digital-base/src/main/java/digital/base/constant/CommonSendStatus.java new file mode 100644 index 0000000..90e9868 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/CommonSendStatus.java @@ -0,0 +1,37 @@ +package digital.base.constant; + +/** + * 系统通告 - 发布状态 + * @Author LeeShaoQing + * + */ +public interface CommonSendStatus { + + /** + * 未发布 + */ + public static final String UNPUBLISHED_STATUS_0 = "0"; + + /** + * 已发布 + */ + public static final String PUBLISHED_STATUS_1 = "1"; + + /** + * 撤销 + */ + public static final String REVOKE_STATUS_2 = "2"; + + /** + * app端推送会话标识后缀 + */ + public static final String APP_SESSION_SUFFIX = "_app"; + + + /**流程催办——系统通知消息模板*/ + public static final String TZMB_BPM_CUIBAN = "bpm_cuiban"; + /**标准模板—系统消息通知*/ + public static final String TZMB_SYS_TS_NOTE = "sys_ts_note"; + /**流程超时提醒——系统通知消息模板*/ + public static final String TZMB_BPM_CHAOSHI_TIP = "bpm_chaoshi_tip"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/DataBaseConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/DataBaseConstant.java new file mode 100644 index 0000000..d99c7a4 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/DataBaseConstant.java @@ -0,0 +1,156 @@ +package digital.base.constant; +/** + * 数据库上下文常量 + * @author: smcp + */ +public interface DataBaseConstant { + //*********数据库类型**************************************** + + /**MYSQL数据库*/ + public static final String DB_TYPE_MYSQL = "MYSQL"; + + /** ORACLE*/ + public static final String DB_TYPE_ORACLE = "ORACLE"; + + /**达梦数据库*/ + public static final String DB_TYPE_DM = "DM"; + + /**postgreSQL达梦数据库*/ + public static final String DB_TYPE_POSTGRESQL = "POSTGRESQL"; + + /**sqlserver数据库*/ + public static final String DB_TYPE_SQLSERVER = "SQLSERVER"; + + /**mariadb 数据库*/ + public static final String DB_TYPE_MARIADB = "MARIADB"; + + /**DB2 数据库*/ + public static final String DB_TYPE_DB2 = "DB2"; + + /**HSQL 数据库*/ + public static final String DB_TYPE_HSQL = "HSQL"; + +// // 数据库类型,对应 database_type 字典 +// public static final String DB_TYPE_MYSQL_NUM = "1"; +// public static final String DB_TYPE_MYSQL7_NUM = "6"; +// public static final String DB_TYPE_ORACLE_NUM = "2"; +// public static final String DB_TYPE_SQLSERVER_NUM = "3"; +// public static final String DB_TYPE_POSTGRESQL_NUM = "4"; +// public static final String DB_TYPE_MARIADB_NUM = "5"; + + //*********系统上下文变量**************************************** + /** + * 数据-所属机构编码 + */ + public static final String SYS_ORG_CODE = "sysOrgCode"; + /** + * 数据-所属机构编码 + */ + public static final String SYS_ORG_CODE_TABLE = "sys_org_code"; + /** + * 数据-所属机构编码 + */ + public static final String SYS_MULTI_ORG_CODE = "sysMultiOrgCode"; + /** + * 数据-所属机构编码 + */ + public static final String SYS_MULTI_ORG_CODE_TABLE = "sys_multi_org_code"; + /** + * 数据-系统用户编码(对应登录用户账号) + */ + public static final String SYS_USER_CODE = "sysUserCode"; + /** + * 数据-系统用户编码(对应登录用户账号) + */ + public static final String SYS_USER_CODE_TABLE = "sys_user_code"; + + /** + * 登录用户真实姓名 + */ + public static final String SYS_USER_NAME = "sysUserName"; + /** + * 登录用户真实姓名 + */ + public static final String SYS_USER_NAME_TABLE = "sys_user_name"; + /** + * 系统日期"yyyy-MM-dd" + */ + public static final String SYS_DATE = "sysDate"; + /** + * 系统日期"yyyy-MM-dd" + */ + public static final String SYS_DATE_TABLE = "sys_date"; + /** + * 系统时间"yyyy-MM-dd HH:mm" + */ + public static final String SYS_TIME = "sysTime"; + /** + * 系统时间"yyyy-MM-dd HH:mm" + */ + public static final String SYS_TIME_TABLE = "sys_time"; + /** + * 数据-所属机构编码 + */ + public static final String SYS_BASE_PATH = "sys_base_path"; + //*********系统上下文变量**************************************** + + + //*********系统建表标准字段**************************************** + /** + * 创建者登录名称 + */ + public static final String CREATE_BY_TABLE = "create_by"; + /** + * 创建者登录名称 + */ + public static final String CREATE_BY = "createBy"; + /** + * 创建日期时间 + */ + public static final String CREATE_TIME_TABLE = "create_time"; + /** + * 创建日期时间 + */ + public static final String CREATE_TIME = "createTime"; + /** + * 更新用户登录名称 + */ + public static final String UPDATE_BY_TABLE = "update_by"; + /** + * 更新用户登录名称 + */ + public static final String UPDATE_BY = "updateBy"; + /** + * 更新日期时间 + */ + public static final String UPDATE_TIME = "updateTime"; + /** + * 更新日期时间 + */ + public static final String UPDATE_TIME_TABLE = "update_time"; + + /** + * 业务流程状态 + */ + public static final String BPM_STATUS = "bpmStatus"; + /** + * 业务流程状态 + */ + public static final String BPM_STATUS_TABLE = "bpm_status"; + //*********系统建表标准字段**************************************** + + + /** + * 租户ID 实体字段名 + */ + String TENANT_ID = "tenantId"; + /** + * 租户ID 数据库字段名 + */ + String TENANT_ID_TABLE = "tenant_id"; + + /** + * sql语句 where + */ + String SQL_WHERE = "where"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/DictConstants.java b/digital-common/digital-base/src/main/java/digital/base/constant/DictConstants.java new file mode 100644 index 0000000..25dd4ae --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/DictConstants.java @@ -0,0 +1,82 @@ +package digital.base.constant; + +/** + * author: smcp + * date:2022-08-10 15:02 + * description: + **/ +public interface DictConstants { + + /** + * 前端区域表信息查询 + */ + public static final String FRONT_DICT_SMCP_AREA = "smcp_area"; + + /** + * 客户端系统设置 系统语言 中文 + */ + public static final String CLIENT_SYSTEM_LANGUAGE_CHINESE = "1"; + + /** + * 客户端系统设置 系统语言 繁体 + */ + public static final String CLIENT_SYSTEM_LANGUAGE_TRADITIONAL = "2"; + + /** + * 客户端系统设置 系统语言 英文 + */ + public static final String CLIENT_SYSTEM_LANGUAGE_ENGLISH = "3"; + + + + /** + * 客户端系统设置 系统语言 key + */ + public static final String CLIENT_SYSTEM_LANGUAGE_KEY = "system-language"; + + /** + * 字典 系统语言 dict_code + */ + public static final String DCIT_SYSTEM_LANGUAGE_KEY = "sys_language"; + + /** + * 客户端系统设置 自动下载 key + */ + public static final String CLIENT_AUTOMATIC_DOWNLOAD_KEY = "auto-download"; + + /** + * 客户端系统设置 播放速度 key + */ + public static final String CLIENT_SWITCH_SPEED_KEY = "switch-speed"; + + /** + * 客户端系统设置 清理缓冲 key + */ + public static final String CLIENT_CLEAR_CACHE = "clear-cache"; + + + /** + * 客户端系统设置 隐私条款 key + */ + public static final String CLIENT_PRIVACY_POLICY = "privacy-policy"; + + /** + * 客户端系统设置 软件版本 key + */ + public static final String CLIENT_SOFTWARE_VERSION = "software-version"; + + /** + * 播放速度 编号 + */ + public static final String SWITCH_SPEED = "switch_speed"; + + /** + * 自动下载 编号 + */ + public static final String AUTOMATIC_DOWNLOAD = "auto-download"; + + /** + * 系统语言 编号 + */ + public static final String SYS_LANGUAGE = "sys_language"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/Face3dSeverHTTPConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/Face3dSeverHTTPConstant.java new file mode 100644 index 0000000..ee94e54 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/Face3dSeverHTTPConstant.java @@ -0,0 +1,63 @@ +package digital.base.constant; + +public interface Face3dSeverHTTPConstant { + + public static final String SWAP_UNDERWEAR = "http://192.168.11.219:8009/cloth/swapInner"; + + public static final String FIGURE_UPLOAD = "http://service.aicloud.fit:6068/bodyManager"; + + public static final String HAIR_UPLOAD = "http://service.aicloud.fit:7393/api/uploadHair/v1"; + + public static final String SWAP_HAIR_v1 = "http://service.aicloud.fit:7393/api/swapHair/v1"; + + public static final String SWAP_HAIR_v2 = "http://service.aicloud.fit:7393/api/swapHair/v2"; + + public static final String CLOTH_UPLOAD = "http://192.168.11.219:8009/cloth/upload"; + + public static final String SWAP_CLOTH = "http://192.168.11.219:8009/cloth/swap"; + + public static final String SWAP_CLOTH_MALE = "http://192.168.11.219:8009/cloth/swapMan"; + + public static final String CRAWLER_VIP = "http://192.168.11.138:9100/api/crawler_vip/v1"; + + + /** + * DRAFT:草稿 IN_PROGRESS:制作中 IN_PROGRESS_FAIL:制作中 SUCCESS:制作成功 FAIL:制作失败 + */ + + public static final String CREATE_STATUS_CANCEL = "CANCEL"; + + public static final String CREATE_STATUS_DRAFT = "DRAFT"; + + public static final String CREATE_STATUS_IN_PROGRESS = "IN_PROGRESS"; + + /** + * DRAFT:草稿 IN_PROGRESS:制作中 IN_PROGRESS_FAIL:制作中 SUCCESS:制作成功 FAIL:制作失败 + */ + public static final String CREATE_STATUS_SUCCESS = "SUCCESS"; + /** + * DRAFT:草稿 IN_PROGRESS:制作中 IN_PROGRESS_FAIL:制作中 SUCCESS:制作成功 FAIL:制作失败 + */ + public static final String CREATE_STATUS_FAIL = "FAIL"; + + public static final String result_success = "success"; + + public static final String result_fail = "FAIL"; + + /** + * 共享盘 存 衣服 + */ + public static final String UPLOADED_FOLDER_CLOTH = "/cloth/"; + + /** + * 共享盘 存 模特 + */ + public static final String UPLOADED_FOLDER_MODEL = "/model/"; + + /** + * 共享盘 存 平铺图 + */ + public static final String UPLOADED_FOLDER_TILE = "/tile/"; + + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/FillRuleConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/FillRuleConstant.java new file mode 100644 index 0000000..65db178 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/FillRuleConstant.java @@ -0,0 +1,25 @@ +package digital.base.constant; + +/** + * 规则值生成 编码常量类 + * @author: taoyan + * @date: 2020年04月02日 + */ +public class FillRuleConstant { + + /** + * 公文发文编码 + */ + public static final String DOC_SEND = "doc_send_code"; + + /** + * 部门编码 + */ + public static final String DEPART = "org_num_role"; + + /** + * 分类字典编码 + */ + public static final String CATEGORY = "category_code_rule"; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/GlobalConstants.java b/digital-common/digital-base/src/main/java/digital/base/constant/GlobalConstants.java new file mode 100644 index 0000000..ac981f9 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/GlobalConstants.java @@ -0,0 +1,23 @@ +package digital.base.constant; + +/** +* @Description: GlobalConstants +* @author: scott +* @date: 2020/01/01 16:01 +*/ +public class GlobalConstants { + + /** + * 业务处理器beanName传递参数 + */ + public static final String HANDLER_NAME = "handlerName"; + /** + * 路由刷新触发器 + */ + public static final String LODER_ROUDER_HANDLER = "loderRouderHandler"; + + /** + * redis消息通道名称 + */ + public static final String REDIS_TOPIC_NAME="jeecg_redis_topic"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/LanguageTypeConstants.java b/digital-common/digital-base/src/main/java/digital/base/constant/LanguageTypeConstants.java new file mode 100644 index 0000000..d9d1357 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/LanguageTypeConstants.java @@ -0,0 +1,55 @@ +package digital.base.constant; + +/** + * author: damao + * date:2022-08-30 22:20 + * description: + **/ +public interface LanguageTypeConstants { + + + /** + * 该值不可用,系统中已存在 + */ + public static final String LANGUAGE_TYPE_DUPLICATE_CHECK = "该值不可用,系统中已存在!"; + /** + * 添加成功 + */ + public static final String LANGUAGE_TYPE_ADD_SUCCESS = "添加成功!"; + /** + * 操作失败 + */ + public static final String LANGUAGE_TYPE_OPERATE_FAIL = "操作失败!"; + /** + * 操作成功 + */ + public static final String LANGUAGE_TYPE_OPERATE_SUCCESS = "操作成功!"; + + /** + * 编辑成功 + */ + public static final String LANGUAGE_TYPE_EDIT_SUCCESS = "编辑成功!"; + /** + * 删除成功 + */ + public static final String LANGUAGE_TYPE_DELETE_SUCCESS = "删除成功!"; + /** + * 批量删除成功 + */ + public static final String LANGUAGE_TYPE_BATCH_DELETE_SUCCESS = "批量删除成功!"; + + /** + * 未找到对应数据 + */ + public static final String LANGUAGE_TYPE_NO_DATA = "未找到对应数据!"; + /** + * 登录成功 + */ + public static final String LANGUAGE_TYPE_LOGIN_SUCCESS = "登录成功!"; + + + /** + * 退出登录成功 + */ + public static final String LANGUAGE_TYPE_LOG_OUT_SUCCESSFULLY = "退出登录成功!"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/RoleConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/RoleConstant.java new file mode 100644 index 0000000..566762b --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/RoleConstant.java @@ -0,0 +1,24 @@ +package digital.base.constant; + +/** + * author: damao + * date:2022-08-27 17:12 + * description: + **/ +public interface RoleConstant { + + /** + * 角色id 超级管理员 + */ + public static final String SUPER_ADMIN_ROLE_ID = "1562999412925894658"; + + /** + * 角色id 系统管理员 + */ + public static final String SYS_ADMIN_ROLE_ID = "f6817f48af4fb3af11b9e8bf182f618b"; + + /** + * 角色id 区域管理员 + */ + public static final String AREA_ADMIN_ROLE_ID = "1559512408061796353"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/ServiceNameConstants.java b/digital-common/digital-base/src/main/java/digital/base/constant/ServiceNameConstants.java new file mode 100644 index 0000000..3549721 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/ServiceNameConstants.java @@ -0,0 +1,42 @@ +/* + * + * * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com). + * *

+ * * Licensed under the GNU Lesser General Public License 3.0 (the "License"); + * * you may not use this file except in compliance with the License. + * * You may obtain a copy of the License at + * *

+ * * https://www.gnu.org/licenses/lgpl.html + * *

+ * * 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 digital.base.constant; + +/** + * @author scott + * @date 2019年05月18日 + * 服务名称 + */ +public interface ServiceNameConstants { + + /** + * 微服务名:系统管理模块 + */ + String SERVICE_SYSTEM = "jeecg-system"; + /** + * 微服务名:Demo模块 + */ + String SERVICE_DEMO = "jeecg-demo"; + + /** + * gateway通过header传递根路径 basePath + */ + String X_GATEWAY_BASE_PATH = "X_GATEWAY_BASE_PATH"; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/ShortVideoOfflineComConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/ShortVideoOfflineComConstant.java new file mode 100644 index 0000000..9b52202 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/ShortVideoOfflineComConstant.java @@ -0,0 +1,74 @@ +package digital.base.constant; + +public interface ShortVideoOfflineComConstant { + + public static final String result_success = "success"; + + public static final String result_fail = "FAIL"; + + /** + * 正常状态 + */ + public static final String STATUS_NORMAL = "200"; + + // 数字人模型 1.1.1 数字人定制 + public static final String CREATE_DIGITAL_PERSON_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/customizeLiveModel"; + + // 数字人模型 1.1.2 音色定制 + public static final String CUSTOM_AUDIO_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/audioCustomize"; + + // 数字人模型 1.1.3 数字人名称更新 + public static final String RENAME_PERSON_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/updatePersonAssetName"; + + // 数字人模型 1.1.4 音色名称更新 + public static final String RENAME_AUDIO_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/updateAudioAssetName"; + + // 数字人模型 1.1.5 删除定制模特 + public static final String DEL_PERSON_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/deleteDigitalPersonAsset"; + + // 数字人模型 1.1.6 删除定制音色 + public static final String DEL_AUDIO_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/deleteAudioAsset"; + + // 数字人模型 1.1.7 定制音色查询 + public static final String GET_AUDIO_ASSET_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/getAudioAssetsById"; + + // 数字人模型 1.1.8 定制音色列表查询 + public static final String GET_AUDIO_LIST_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/audioAssetsList"; + + // 数字人模型 1.1.9 定制数字人列表查询 + public static final String GET_CUSTOM_PERSON_LIST_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/customizeAssets"; + + // 数字人模型 1.1.10 免费数字人列表查询 + public static final String GET_FREE_PERSON_LIST_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/freeAssets"; + + // 短视频作品 1.3.1 创建视频合成-利用音频文件 + public static final String CREATE_WITH_AUDIO_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/composeWithAudio"; + + // 短视频作品 1.3.2 创建视频合成-利用tts + public static final String CREATE_WITH_TTS_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/composeWithTTS"; + + // 短视频作品 1.3.3 更新视频作品名称 + public static final String RENAME_VIDEO_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/updateWorkName"; + + // 短视频作品 1.3.4 视频创建任务状态查询 + public static final String GET_VIDEO_STATUS_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/detail "; + + // 短视频作品 1.3.5 视频作品列表 + public static final String GET_VIDEO_LIST_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/workList"; + + // 短视频作品 1.3.7 删除视频作品 + public static final String DEL_VIDEO_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/deleteWork"; + + // 短视频作品 1.3.8 复制视频作品 + public static final String COPY_VIDEO_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/copyWork"; + + // 短视频作品 1.3.9 视频作品统计 + public static final String COUNT_VIDEO_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/videoStatistics"; + + //========================================================下面是本地算法============================================================== + + // 创建数字人定制任务-请求算法(新增) + public static final String CUSTOM_CREATE_TASK_HTTP = "http://service.aicloud.fit:9008/train/v1"; + + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/SymbolConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/SymbolConstant.java new file mode 100644 index 0000000..c076725 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/SymbolConstant.java @@ -0,0 +1,89 @@ +package digital.base.constant; + +/** + * @Description: 符号和特殊符号常用类 + * @author: wangshuai + * @date: 2022年03月30日 17:44 + */ +public class SymbolConstant { + + /** + * 符号:点 + */ + public static final String SPOT = "."; + + /** + * 符号:双斜杠 + */ + public static final String DOUBLE_BACKSLASH = "\\"; + + /** + * 符号:冒号 + */ + public static final String COLON = ":"; + + /** + * 符号:逗号 + */ + public static final String COMMA = ","; + + /** + * 符号:左花括号 } + */ + public static final String LEFT_CURLY_BRACKET = "{"; + + /** + * 符号:右花括号 } + */ + public static final String RIGHT_CURLY_BRACKET = "}"; + + /** + * 符号:井号 # + */ + public static final String WELL_NUMBER = "#"; + + /** + * 符号:单斜杠 + */ + public static final String SINGLE_SLASH = "/"; + + /** + * 符号:双斜杠 + */ + public static final String DOUBLE_SLASH = "//"; + + /** + * 符号:感叹号 + */ + public static final String EXCLAMATORY_MARK = "!"; + + /** + * 符号:下划线 + */ + public static final String UNDERLINE = "_"; + + /** + * 符号:单引号 + */ + public static final String SINGLE_QUOTATION_MARK = "'"; + + /** + * 符号:星号 + */ + public static final String ASTERISK = "*"; + + /** + * 符号:百分号 + */ + public static final String PERCENT_SIGN = "%"; + + /** + * 符号:美元 $ + */ + public static final String DOLLAR = "$"; + + /** + * 符号:和 & + */ + public static final String AND = "&"; +} \ No newline at end of file diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/UserFileConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/UserFileConstant.java new file mode 100644 index 0000000..f925470 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/UserFileConstant.java @@ -0,0 +1,62 @@ +package digital.base.constant; + +/** + * author: smcp + * date:2022-08-26 9:41 + * description: + **/ +public interface UserFileConstant { + + /** + * 是否是 临时文件 0 不是 + * + */ + public static final String IS_TEMP_NO = "0"; + + /** + * 是否是 临时文件 1 是 + * + */ + public static final String IS_TEMP_YES = "1"; + /** + * 文件类型 1 图片 + * + */ + public static final String FILE_TYPE_IMAGE = "1"; + /** + * 文件类型 2 pdf + * + */ + public static final String FILE_TYPE_PDF = "2"; + + /** + * 是否是文件夹 0 不是 + * + */ + public static final Integer IS_DIR_NO = 0; + + /** + * 是否是文件夹 1 是文件夹 + * + */ + public static final Integer IS_DIR_YES = 1; + + + /** + * 文件下载状态 1开始下载 + * + */ + public static final String file_download_status_begin = "1"; + + /** + * + * 文件下载状态 2下载完成 + */ + public static final String file_download_status_end = "2"; + + /** + * + * 文件下载状态 3下载失败 + */ + public static final String file_download_status_error = "3"; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/VideoConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/VideoConstant.java new file mode 100644 index 0000000..76c4b7c --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/VideoConstant.java @@ -0,0 +1,35 @@ +package digital.base.constant; + +public interface VideoConstant { + + public static final String result_success = "success"; + + public static final String result_fail = "fail"; + + public static final Integer source_type_0 = 0; + + /** + * 文本生成:1 + * 音频生成:2 + * 不同入参必传参数不一样 + */ + + public static final String video_Type_text = "1"; + /** + * 文本生成:1 + * 音频生成:2 + * 不同入参必传参数不一样 + */ + + public static final String video_Type_audio = "2"; + /** + * 正常状态 + */ + public static final String STATUS_NORMAL = "200"; + + // 1.2.1 音色列表 + public static final String GET_VOICE_LIST_HTTP = "https://meta.yiwise.com/openApiDigitalPerson/customer/audioAssetsList"; + + + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/VxeSocketConst.java b/digital-common/digital-base/src/main/java/digital/base/constant/VxeSocketConst.java new file mode 100644 index 0000000..2b227f9 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/VxeSocketConst.java @@ -0,0 +1,33 @@ +package digital.base.constant; + +/** + * VXESocket 常量 + * + * update: 【类名改了大小写】 date: 2022-04-18 + * @author: smcp + */ +public class VxeSocketConst { + + /** + * 消息类型 + */ + public static final String TYPE = "type"; + /** + * 消息数据 + */ + public static final String DATA = "data"; + + /** + * 消息类型:心跳检测 + */ + public static final String TYPE_HB = "heart_beat"; + /** + * 消息类型:通用数据传递 + */ + public static final String TYPE_CSD = "common_send_date"; + /** + * 消息类型:更新vxe table数据 + */ + public static final String TYPE_UVT = "update_vxe_table"; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/WebsocketConst.java b/digital-common/digital-base/src/main/java/digital/base/constant/WebsocketConst.java new file mode 100644 index 0000000..def8cc6 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/WebsocketConst.java @@ -0,0 +1,61 @@ +package digital.base.constant; + +/** + * @Description: Websocket常量类 + * @author: taoyan + * @date: 2020年03月23日 + */ +public class WebsocketConst { + + + /** + * 消息json key:cmd + */ + public static final String MSG_CMD = "cmd"; + + /** + * 消息json key:msgId + */ + public static final String MSG_ID = "msgId"; + + /** + * 消息json key:msgTxt + */ + public static final String MSG_TXT = "msgTxt"; + + /** + * 消息json key:userId + */ + public static final String MSG_USER_ID = "userId"; + + /** + * 消息类型 heartcheck + */ + public static final String CMD_CHECK = "heartcheck"; + + /** + * 消息类型 user 用户消息 + */ + public static final String CMD_USER = "user"; + + /** + * 消息类型 topic 系统通知 + */ + public static final String CMD_TOPIC = "topic"; + + /** + * 消息类型 email + */ + public static final String CMD_EMAIL = "email"; + + /** + * 消息类型 meetingsign 会议签到 + */ + public static final String CMD_SIGN = "sign"; + + /** + * 消息类型 新闻发布/取消 + */ + public static final String NEWS_PUBLISH = "publish"; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/constant/ZitaCommonConstant.java b/digital-common/digital-base/src/main/java/digital/base/constant/ZitaCommonConstant.java new file mode 100644 index 0000000..ec41868 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/constant/ZitaCommonConstant.java @@ -0,0 +1,64 @@ +package digital.base.constant; + +public interface ZitaCommonConstant { + + /** + * 性别男 + */ + public static final String sex_male = "male"; + + /** + * 性别女 + */ + public static final String sex_female = "female"; + + /** + * 性别男 hairs + */ + public static final String sex_male_hairs = "[\"nan_tf_69\", \"nan_tf_92\", \"nan_tf_102\", \"nan_tf_142\", \"nan_tf_129\"]"; + + /** + * 性别女 hairs + */ + public static final String sex_female_hairs ="[\"nv_tf_128\", \"nv_tf_175\", \"nv_tf_132\", \"nv_tf_159\", \"nv_tf_161\"]"; + + /** + * 正常状态 + */ + public static final String STATUS_NORMAL = "200"; + + /** + * 生成图片和模型 1 + */ + public static final String TASK_TYPE_PICTURE = "1"; + /** + * 生成视频 2 + */ + public static final String TASK_TYPE_VIDEO = "2"; + + /** + * 新用户注册送5次试用机会 + */ + public static final Integer New_register_member_try_times = 5; + + /** + * 购买卡类型-试用 + */ + public static final String MEMBER_TYPE_TRY_CARD = "1"; + + /** + * 购买卡类型-次卡 + */ + public static final String MEMBER_TYPE_SUB_CARD = "2"; + + /** + * 购买卡类型-月卡 + */ + public static final String MEMBER_TYPE_MONTH_CARD = "3"; + + /** + * 购买卡类型-年卡 + */ + public static final String MEMBER_TYPE_YEAR_CARD = "4"; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/CgformEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/CgformEnum.java new file mode 100644 index 0000000..5c77b56 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/CgformEnum.java @@ -0,0 +1,151 @@ +package digital.base.enums; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * online表单枚举 代码生成器用到 + * + * @author: smcp + */ +public enum CgformEnum { + + /** + * 单表 + */ + ONE(1, "one", "/jeecg/code-template-online", "default.one", "经典风格"), + /** + * 多表 + */ + MANY(2, "many", "/jeecg/code-template-online", "default.onetomany", "经典风格"), + /** + * 多表 + */ + ERP(2, "erp", "/jeecg/code-template-online", "erp.onetomany", "ERP风格"), + /** + * 多表(jvxe风格) + */ + JVXE_TABLE(2, "jvxe", "/jeecg/code-template-online", "jvxe.onetomany", "JVXE风格"), + /** + * 多表(内嵌子表风格) + */ + INNER_TABLE(2, "innerTable", "/jeecg/code-template-online", "inner-table.onetomany", "内嵌子表风格"), + /** + * 多表(tab风格) + */ + TAB(2, "tab", "/jeecg/code-template-online", "tab.onetomany", "Tab风格"), + /** + * 树形列表 + */ + TREE(3, "tree", "/jeecg/code-template-online", "default.tree", "树形列表"); + + /** + * 类型 1/单表 2/一对多 3/树 + */ + int type; + /** + * 编码标识 + */ + String code; + /** + * 代码生成器模板路径 + */ + String templatePath; + /** + * 代码生成器模板路径 + */ + String stylePath; + /** + * 模板风格名称 + */ + String note; + + /** + * 构造器 + * + * @param type 类型 1/单表 2/一对多 3/树 + * @param code 模板编码 + * @param templatePath 模板路径 + * @param stylePath 模板子路径 + * @param note + */ + CgformEnum(int type, String code, String templatePath, String stylePath, String note) { + this.type = type; + this.code = code; + this.templatePath = templatePath; + this.stylePath = stylePath; + this.note = note; + } + + /** + * 根据code获取模板路径 + * + * @param code + * @return + */ + public static String getTemplatePathByConfig(String code) { + return getCgformEnumByConfig(code).templatePath; + } + + /** + * 根据code找枚举 + * + * @param code + * @return + */ + public static CgformEnum getCgformEnumByConfig(String code) { + for (CgformEnum e : CgformEnum.values()) { + if (e.code.equals(code)) { + return e; + } + } + return null; + } + + /** + * 根据类型找所有 + * + * @param type + * @return + */ + public static List> getJspModelList(int type) { + List> ls = new ArrayList>(); + for (CgformEnum e : CgformEnum.values()) { + if (e.type == type) { + Map map = new HashMap(); + map.put("code", e.code); + map.put("note", e.note); + ls.add(map); + } + } + return ls; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getTemplatePath() { + return templatePath; + } + + public void setTemplatePath(String templatePath) { + this.templatePath = templatePath; + } + + public String getStylePath() { + return stylePath; + } + + public void setStylePath(String stylePath) { + this.stylePath = stylePath; + } + + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeEnum.java new file mode 100644 index 0000000..5b939fd --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeEnum.java @@ -0,0 +1,58 @@ +package digital.base.enums; + +/** + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/7/13! + */ +public enum FileTypeEnum { + picture_1("1", "bmp"), + picture_2("1", "jpg"), + picture_3("1", "png"), + picture_4("1", "tif"), + picture_5("1", "gif"), + picture_6("1", "jpeg"), + document_1("2", "pdf"), + ; + + FileTypeEnum(String fileType, String extendName) { + this.fileType = fileType; + this.extendName = extendName; + } + + public String getFileType() { + return fileType; + } + + public void setFileType(String fileType) { + this.fileType = fileType; + } + + public String getExtendName() { + return extendName; + } + + public void setExtendName(String extendName) { + this.extendName = extendName; + } + + private String fileType; + private String extendName; + + + public static FileTypeEnum codeIn(String extendName) { + if (extendName == null) { + return null; + } else { + for (FileTypeEnum em : FileTypeEnum.values()) { + if (em.getExtendName().equals(extendName)) { + return em; + } + } + return null; + } + } + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeKSFEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeKSFEnum.java new file mode 100644 index 0000000..582eb3a --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/FileTypeKSFEnum.java @@ -0,0 +1,74 @@ +package digital.base.enums; + +import java.util.Arrays; +import java.util.List; + +/** + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/7/13! + */ +public enum FileTypeKSFEnum { + IDCACRD_1(1,"idcard1","sys_user","id","身份证正面"), + IDCACRD_2(2,"idcard2","sys_user","id","身份证反面"), + IMPORTPERSON(3,"importperson","sys_user","id",""), + IMPORTENDRESULT(4,"importEndResult","insurance_case","id",""), + EXPORTJT(5,"exportjt","insurance_case","id",""), + EXPORTWT(6,"exportwt","insurance_case","id",""), + USERCHANGE(7,"userchange","sys_user","id",""), + CASEDETAILFILE(8,"casedetailfile","caseid","id",""), + BANKFRONT(9,"bank1","sys_user","id","银行卡正面"), + BANKBACk(10,"bank2","sys_user","id","银行卡反面"), + ; + FileTypeKSFEnum(Integer key, String value, String tableName, String tableId, String name) { + this.key = key; + this.value = value; + this.tableName = tableName; + this.tableId = tableId; + this.name = name; + } + private Integer key; + private String value; + private String tableName; + private String tableId; + private String name; + public Integer getKey() { + return key; + } + public String getValue() { + return value; + } + public String getTableName() { + return tableName; + } + public String getTableId() { + return tableId; + } + public String getName() { + return name; + } + public static FileTypeKSFEnum codeIn(Integer code) { + if (code == null) { + return null; + } else { + for (FileTypeKSFEnum em : FileTypeKSFEnum.values()) { + if (em.getKey().equals(code)) { + return em; + } + } + return null; + } + } + public static List getNeedIdCard(){ + return Arrays.asList(IDCACRD_1.getKey(),IDCACRD_2.getKey(),BANKBACk.getKey(),BANKFRONT.getKey()); + } + + public static List getUserPhotoTypes() { + return Arrays.asList(IDCACRD_1.getKey().toString(), IDCACRD_2.getKey().toString(),BANKBACk.getKey().toString(),BANKFRONT.getKey().toString()); + } + public static List getUserEcportCards() { + return Arrays.asList(IDCACRD_1.getKey().toString(), IDCACRD_2.getKey().toString(),BANKBACk.getKey().toString(),BANKFRONT.getKey().toString()); + } +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/LowAppAopEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/LowAppAopEnum.java new file mode 100644 index 0000000..b70923b --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/LowAppAopEnum.java @@ -0,0 +1,24 @@ +package digital.base.enums; + +/** + * LowApp 切面注解枚举 + * + * @date 2022-1-5 + * @author: smcp + */ +public enum LowAppAopEnum { + + /** + * 新增方法 + */ + ADD, + /** + * 删除方法(包含单个和批量删除) + */ + DELETE, + + /** + * Online表单专用:数据库表转Online表单 + */ + CGFORM_DB_IMPORT +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/ModuleType.java b/digital-common/digital-base/src/main/java/digital/base/enums/ModuleType.java new file mode 100644 index 0000000..78a8bd1 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/ModuleType.java @@ -0,0 +1,19 @@ +package digital.base.enums; + +/** + * 日志按模块分类 + * + * @author: smcp + */ +public enum ModuleType { + + /** + * 普通 + */ + COMMON, + + /** + * online + */ + ONLINE; +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/OperateTypeEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/OperateTypeEnum.java new file mode 100644 index 0000000..1e58808 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/OperateTypeEnum.java @@ -0,0 +1,95 @@ +package digital.base.enums; + + +import digital.base.constant.CommonConstant; + +/** + * @Description: 操作类型 + * @author: smcp + * @date: 2022/3/31 10:05 + */ +public enum OperateTypeEnum { + + /** + * 列表 + */ + LIST(CommonConstant.OPERATE_TYPE_1, "list"), + + /** + * 新增 + */ + ADD(CommonConstant.OPERATE_TYPE_2, "add"), + + /** + * 编辑 + */ + EDIT(CommonConstant.OPERATE_TYPE_3, "edit"), + + /** + * 删除 + */ + DELETE(CommonConstant.OPERATE_TYPE_4, "delete"), + + /** + * 导入 + */ + IMPORT(CommonConstant.OPERATE_TYPE_5, "import"), + + /** + * 导出 + */ + EXPORT(CommonConstant.OPERATE_TYPE_6, "export"); + + /** + * 类型 1列表,2新增,3编辑,4删除,5导入,6导出 + */ + int type; + + /** + * 编码(请求方式) + */ + String code; + + + /** + * 构造器 + * + * @param type 类型 + * @param code 编码(请求方式) + */ + OperateTypeEnum(int type, String code) { + this.type = type; + this.code = code; + } + + /** + * 根据请求名称匹配 + * + * @param methodName 请求名称 + * @return Integer 类型 + */ + public static Integer getTypeByMethodName(String methodName) { + for (OperateTypeEnum e : OperateTypeEnum.values()) { + if (methodName.startsWith(e.getCode())) { + return e.getType(); + } + } + return CommonConstant.OPERATE_TYPE_1; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/SMCodeMessage.java b/digital-common/digital-base/src/main/java/digital/base/enums/SMCodeMessage.java new file mode 100644 index 0000000..b4ce29a --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/SMCodeMessage.java @@ -0,0 +1,15 @@ +package digital.base.enums; + +/** + * 基础消息类 + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/6/27! + */ +public interface SMCodeMessage { + Integer getKey(); + String getValue(); + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/SentinelErrorInfoEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/SentinelErrorInfoEnum.java new file mode 100644 index 0000000..5ff8265 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/SentinelErrorInfoEnum.java @@ -0,0 +1,108 @@ +package digital.base.enums; + +/** + * @Description: 异常错误信息定义 + * @author: zyf + * @date: 2022/4/14 10:05 + */ +public enum SentinelErrorInfoEnum { + + /** + * 流控异常 + */ + FlowException("访问频繁,请稍候再试"), + + /** + * 热点参数异常 + */ + ParamFlowException("热点参数限流"), + + /** + * 系统规则限流或降级 + */ + SystemBlockException("系统规则限流或降级"), + + /** + * 授权规则不通过 + */ + AuthorityException("授权规则不通过"), + + /** + * 授权规则不通过 + */ + UnknownError("未知异常"), + + /** + * 服务降级 + */ + DegradeException("服务降级"); + + + /** + * 错误信息 + */ + String error; + + /** + * 错误代码 + */ + Integer code; + + + public String getError() { + return error; + } + + public void setError(String error) { + this.error = error; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + /** + * 构造器 + * + * @param error 错误信息 + * @param code 错误代码 + */ + SentinelErrorInfoEnum(String error, Integer code) { + this.error = error; + this.code = code; + } + + /** + * 构造器 + * + * @param error 错误信息 + */ + SentinelErrorInfoEnum(String error) { + this.error = error; + this.code = 500; + } + + /** + * 根据异常名称匹配 + * + * @param throwable 异常 + * @return String 错误信息 + */ + public static SentinelErrorInfoEnum getErrorByException(Throwable throwable) { + if(throwable==null){ + return null; + } + + String exceptionClass=throwable.getClass().getSimpleName(); + for (SentinelErrorInfoEnum e : SentinelErrorInfoEnum.values()) { + if (exceptionClass.equals(e.name())) { + return e; + } + } + return null; + } +} diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/UrlMatchEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/UrlMatchEnum.java new file mode 100644 index 0000000..7b88f37 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/UrlMatchEnum.java @@ -0,0 +1,66 @@ +package digital.base.enums; + +/** + * @Author scott + * @Date 2020/1/14 13:36 + * @Description: 请求URL与菜单路由URL转换规则(方便于采用菜单路由URL来配置数据权限规则) + */ +public enum UrlMatchEnum { + /**求URL与菜单路由URL转换规则 /online/cgform/api/getData/ */ + CGFORM_DATA("/online/cgform/api/getData/", "/online/cgformList/"), + /**求URL与菜单路由URL转换规则 /online/cgform/api/exportXls/ */ + CGFORM_EXCEL_DATA("/online/cgform/api/exportXls/", "/online/cgformList/"), + /**求URL与菜单路由URL转换规则 /online/cgform/api/getTreeData/ */ + CGFORM_TREE_DATA("/online/cgform/api/getTreeData/", "/online/cgformList/"), + /**求URL与菜单路由URL转换规则 /online/cgreport/api/getColumnsAndData/ */ + CGREPORT_DATA("/online/cgreport/api/getColumnsAndData/", "/online/cgreport/"), + /**求URL与菜单路由URL转换规则 /online/cgreport/api/exportXls/ */ + CGREPORT_EXCEL_DATA("/online/cgreport/api/exportXls/", "/online/cgreport/"), + /**求URL与菜单路由URL转换规则 /online/cgreport/api/exportManySheetXls/ */ + CGREPORT_EXCEL_DATA2("/online/cgreport/api/exportManySheetXls/", "/online/cgreport/"); + + UrlMatchEnum(String url, String matchUrl) { + this.url = url; + this.matchUrl = matchUrl; + } + + /** + * Request 请求 URL前缀 + */ + private String url; + /** + * 菜单路由 URL前缀 (对应菜单路径) + */ + private String matchUrl; + + /** + * 根据req url 获取到菜单配置路径(前端页面路由URL) + * + * @param url + * @return + */ + public static String getMatchResultByUrl(String url) { + //获取到枚举 + UrlMatchEnum[] values = UrlMatchEnum.values(); + //加强for循环进行遍历操作 + for (UrlMatchEnum lr : values) { + //如果遍历获取的type和参数type一致 + if (url.indexOf(lr.url) != -1) { + //返回type对象的desc + return url.replace(lr.url, lr.matchUrl); + } + } + return null; + } + + public String getMatchUrl() { + return matchUrl; + } + // public static void main(String[] args) { +// /** +// * 比如request真实请求URL: /online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a +// * 转换匹配路由URL后(对应配置的菜单路径):/online/cgformList/81fcf7d8922d45069b0d5ba983612d3a +// */ +// System.out.println(UrlMatchEnum.getMatchResultByUrl("/online/cgform/api/getData/81fcf7d8922d45069b0d5ba983612d3a")); +// } +} \ No newline at end of file diff --git a/digital-common/digital-base/src/main/java/digital/base/enums/YesOrNoEnum.java b/digital-common/digital-base/src/main/java/digital/base/enums/YesOrNoEnum.java new file mode 100644 index 0000000..0bd0f5f --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/enums/YesOrNoEnum.java @@ -0,0 +1,41 @@ +package digital.base.enums; + + +/** + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/6/27! + */ +public enum YesOrNoEnum implements SMCodeMessage{ + YES(1,"是"), + NO(0,"否"); + YesOrNoEnum(Integer key, String value) { + this.key = key; + this.value = value; + } + + private Integer key; + private String value; + @Override + public Integer getKey() { + return key; + } + @Override + public String getValue() { + return value; + } + public static YesOrNoEnum codeIn(Integer code) { + if (code == null) { + return null; + } else { + for (YesOrNoEnum em : YesOrNoEnum.values()) { + if (em.getKey().equals(code)) { + return em; + } + } + return null; + } + } +} diff --git a/digital-common/digital-base/src/main/java/digital/base/handler/IFillRuleHandler.java b/digital-common/digital-base/src/main/java/digital/base/handler/IFillRuleHandler.java new file mode 100644 index 0000000..565b99b --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/handler/IFillRuleHandler.java @@ -0,0 +1,22 @@ +package digital.base.handler; + +import com.alibaba.fastjson.JSONObject; + +/** + * 填值规则接口 + * + * @author Yan_东 + * 如需使用填值规则功能,规则实现类必须实现此接口 + */ +public interface IFillRuleHandler { + + /** + * 填值规则 + * @param params 页面配置固定参数 + * @param formData 动态表单参数 + * @return + */ + public Object execute(JSONObject params, JSONObject formData); + +} + diff --git a/digital-common/digital-base/src/main/java/digital/base/vo/LoginUser.java b/digital-common/digital-base/src/main/java/digital/base/vo/LoginUser.java new file mode 100644 index 0000000..62897af --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/vo/LoginUser.java @@ -0,0 +1,92 @@ +package digital.base.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 在线用户信息 + *

+ * + * @Author scott + * @since 2018-12-20 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class LoginUser { + + private String id; + + @ApiModelProperty(value = "discordId") + private String discordId; + + @ApiModelProperty(value = "roleType") + private String roleType; + + @ApiModelProperty(value = "appId") + private String appId; + + @ApiModelProperty(value = "姓名") + private String username; + + @ApiModelProperty(value = "剩下使用次数") + private BigDecimal remainNum; + + /** + * 登录人名字 + */ + private String realname; + + /** + * 登录人密码 + */ + private String password; + /** + * 头像 + */ + private String avatar; + + private String roleId; + /** + * 生日 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(1:男 2:女) + */ + private Integer sex; + + /** + * 电子邮件 + */ + private String email; + + /** + * 电话 + */ + private String phone; + + /** + * 状态(1:正常 2:冻结 ) + */ + private Integer status; + + private Integer delFlag; + /** + * 创建时间 + */ + private Date createTime; + private String telephone; + +} diff --git a/digital-common/digital-base/src/main/java/digital/base/vo/Result.java b/digital-common/digital-base/src/main/java/digital/base/vo/Result.java new file mode 100644 index 0000000..25fc9bd --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/vo/Result.java @@ -0,0 +1,241 @@ +package digital.base.vo; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import digital.base.constant.CommonConstant; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * 接口返回数据格式 + * + * @author scott + * @email jeecgos@163.com + * @date 2019年1月19日 + */ +@Data +@ApiModel(value = "接口返回对象", description = "接口返回对象") +public class Result implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 成功标志 + */ + @ApiModelProperty(value = "成功标志") + private boolean success = true; + + /** + * 返回处理消息 + */ + @ApiModelProperty(value = "返回处理消息") + private String message = ""; + + @ApiModelProperty(value = "") + private String requestId; + + @ApiModelProperty(value = "处理中的数据条数") + private Integer inProcessCount; + + /** + * 返回代码 + */ + @ApiModelProperty(value = "返回代码") + private Integer code = 0; + + /** + * 返回数据对象 data + */ + @ApiModelProperty(value = "返回数据对象") + private T result; + + /** + * 时间戳 + */ + @ApiModelProperty(value = "时间戳") + private long timestamp = System.currentTimeMillis(); + @JsonIgnore + private String onlTable; + + public Result() { + } + + /** + * 兼容VUE3版token失效不跳转登录页面 + * + * @param code + * @param message + */ + public Result(Integer code, String message) { + this.code = code; + this.message = message; + } + + public static Result ok() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + return r; + } + + public static Result ok(String msg) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + //Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D + r.setResult((T) msg); + r.setMessage(null); + return r; + } + + public static Result ok(T data, String requestId) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + r.setRequestId(requestId); + return r; + } + + public static Result ok(T data, String requestId, Integer inProcessCount) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + r.setRequestId(requestId); + r.setInProcessCount(inProcessCount); + return r; + } + + public static Result ok(T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + return r; + } + + public static Result OK() { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + return r; + } + + /** + * 此方法是为了兼容升级所创建 + * + * @param msg + * @param + * @return + */ + public static Result OK(String msg) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage(msg); + //Result OK(String msg)方法会造成兼容性问题 issues/I4IP3D + r.setResult((T) msg); + return r; + } + + public static Result OK(T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + return r; + } + + public static Result OK(T data, String taskId) { + Result r = new Result(); + r.setSuccess(true); + r.setRequestId(taskId); + r.setCode(CommonConstant.SC_OK_200); + r.setResult(data); + return r; + } + + public static Result OK(String msg, String taskId) { + Result r = new Result(); + r.setSuccess(true); + r.setRequestId(taskId); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage(msg); + r.setResult((T) msg); + return r; + } + + public static Result OK(String msg, T data) { + Result r = new Result(); + r.setSuccess(true); + r.setCode(CommonConstant.SC_OK_200); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result error(String msg, T data) { + Result r = new Result(); + r.setSuccess(false); + r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); + r.setMessage(msg); + r.setResult(data); + return r; + } + + public static Result error(T data, String msg, String taskId) { + Result r = new Result(); + r.setSuccess(false); + r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); + r.setMessage(msg); + r.setRequestId(taskId); + r.setResult(data); + return r; + } + + public static Result error(String msg) { + return error(CommonConstant.SC_INTERNAL_SERVER_ERROR_500, msg); + } + + public static Result error(int code, String msg) { + Result r = new Result(); + r.setCode(code); + r.setMessage(msg); + r.setSuccess(false); + return r; + } + + public static Result error(String msg, String requestId) { + Result r = new Result(); + r.setCode(CommonConstant.SC_INTERNAL_SERVER_ERROR_500); + r.setMessage(msg); + r.setRequestId(requestId); + r.setSuccess(false); + return r; + } + + /** + * 无权限访问返回结果 + */ + public static Result noauth(String msg) { + return error(CommonConstant.SC_JEECG_NO_AUTHZ, msg); + } + + public Result success(String message) { + this.message = message; + this.code = CommonConstant.SC_OK_200; + this.success = true; + return this; + } + + public Result error500(String message) { + this.message = message; + this.code = CommonConstant.SC_INTERNAL_SERVER_ERROR_500; + this.success = false; + return this; + } + +} \ No newline at end of file diff --git a/digital-common/digital-base/src/main/java/digital/base/vo/SysPermissionDataRuleModel.java b/digital-common/digital-base/src/main/java/digital/base/vo/SysPermissionDataRuleModel.java new file mode 100644 index 0000000..d5dfac3 --- /dev/null +++ b/digital-common/digital-base/src/main/java/digital/base/vo/SysPermissionDataRuleModel.java @@ -0,0 +1,144 @@ +package digital.base.vo; + +import java.util.Date; + +/** + *

+ * 菜单权限规则表 + *

+ * + * @Author huangzhilin + * @since 2019-03-29 + */ +public class SysPermissionDataRuleModel { + + /** + * id + */ + private String id; + + /** + * 对应的菜单id + */ + private String permissionId; + + /** + * 规则名称 + */ + private String ruleName; + + /** + * 字段 + */ + private String ruleColumn; + + /** + * 条件 + */ + private String ruleConditions; + + /** + * 规则值 + */ + private String ruleValue; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 创建人 + */ + private String createBy; + + /** + * 修改时间 + */ + private Date updateTime; + + /** + * 修改人 + */ + private String updateBy; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPermissionId() { + return permissionId; + } + + public void setPermissionId(String permissionId) { + this.permissionId = permissionId; + } + + public String getRuleName() { + return ruleName; + } + + public void setRuleName(String ruleName) { + this.ruleName = ruleName; + } + + public String getRuleColumn() { + return ruleColumn; + } + + public void setRuleColumn(String ruleColumn) { + this.ruleColumn = ruleColumn; + } + + public String getRuleConditions() { + return ruleConditions; + } + + public void setRuleConditions(String ruleConditions) { + this.ruleConditions = ruleConditions; + } + + public String getRuleValue() { + return ruleValue; + } + + public void setRuleValue(String ruleValue) { + this.ruleValue = ruleValue; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } +} diff --git a/digital-common/digital-bean/pom.xml b/digital-common/digital-bean/pom.xml new file mode 100644 index 0000000..760eb89 --- /dev/null +++ b/digital-common/digital-bean/pom.xml @@ -0,0 +1,64 @@ + + + + digital-common + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-bean + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-web + true + + + cn.hutool + hutool-core + + + commons-beanutils + commons-beanutils + + + org.jeecgframework.boot + digital-base + 3.2.0 + compile + + + com.baomidou + mybatis-plus-annotation + 3.5.1 + compile + + + org.jeecgframework + autopoi + 1.4.0 + compile + + + io.swagger + swagger-annotations + 1.5.22 + compile + + + org.jeecgframework.boot + digital-util + 3.2.0 + compile + + + \ No newline at end of file diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/BaseMap.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/BaseMap.java new file mode 100644 index 0000000..ed32732 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/BaseMap.java @@ -0,0 +1,139 @@ +package digital.bean.jeecg; + +import cn.hutool.core.util.ObjectUtil; +import org.apache.commons.beanutils.ConvertUtils; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * BaseMap + * + * @author: scott + * @date: 2020/01/01 16:17 + */ +public class BaseMap extends HashMap { + + private static final long serialVersionUID = 1L; + + + public BaseMap() { + + } + + public BaseMap(Map map) { + this.putAll(map); + } + + public static BaseMap toBaseMap(Map obj) { + BaseMap map = new BaseMap(); + map.putAll(obj); + return map; + } + + @Override + public BaseMap put(String key, Object value) { + super.put(key, Optional.ofNullable(value).orElse("")); + return this; + } + + public BaseMap add(String key, Object value) { + super.put(key, Optional.ofNullable(value).orElse("")); + return this; + } + + @SuppressWarnings("unchecked") + public T get(String key) { + Object obj = super.get(key); + if (ObjectUtil.isNotEmpty(obj)) { + return (T) obj; + } else { + return null; + } + } + + @SuppressWarnings("unchecked") + public Boolean getBoolean(String key) { + Object obj = super.get(key); + if (ObjectUtil.isNotEmpty(obj)) { + return Boolean.valueOf(obj.toString()); + } else { + return false; + } + } + + public Long getLong(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return new Long(v.toString()); + } + return null; + } + + public Long[] getLongs(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return (Long[]) v; + } + return null; + } + + public List getListLong(String key) { + List list = get(key); + if (ObjectUtil.isNotEmpty(list)) { + return list.stream().map(e -> new Long(e)).collect(Collectors.toList()); + } else { + return null; + } + } + + public Long[] getLongIds(String key) { + Object ids = get(key); + if (ObjectUtil.isNotEmpty(ids)) { + return (Long[]) ConvertUtils.convert(ids.toString().split(","), Long.class); + } else { + return null; + } + } + + public Integer getInt(String key, Integer def) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return Integer.parseInt(v.toString()); + } else { + return def; + } + } + + public Integer getInt(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return Integer.parseInt(v.toString()); + } else { + return 0; + } + } + + public BigDecimal getBigDecimal(String key) { + Object v = get(key); + if (ObjectUtil.isNotEmpty(v)) { + return new BigDecimal(v.toString()); + } + return new BigDecimal("0"); + } + + @SuppressWarnings("unchecked") + public T get(String key, T def) { + Object obj = super.get(key); + if (ObjectUtil.isEmpty(obj)) { + return def; + } + return (T) obj; + } + + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileDownDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileDownDTO.java new file mode 100644 index 0000000..5ecdd1e --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileDownDTO.java @@ -0,0 +1,31 @@ +package digital.bean.jeecg.dto; + +import lombok.Data; + +import javax.servlet.http.HttpServletResponse; +import java.io.Serializable; + +/** + * 文件下载 + * cloud api 用到的接口传输对象 + * @author: smcp + */ +@Data +public class FileDownDTO implements Serializable { + + private static final long serialVersionUID = 6749126258686446019L; + + private String filePath; + private String uploadpath; + private String uploadType; + private HttpServletResponse response; + + public FileDownDTO(){} + + public FileDownDTO(String filePath, String uploadpath, String uploadType,HttpServletResponse response){ + this.filePath = filePath; + this.uploadpath = uploadpath; + this.uploadType = uploadType; + this.response = response; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileUploadDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileUploadDTO.java new file mode 100644 index 0000000..d01d032 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/FileUploadDTO.java @@ -0,0 +1,56 @@ +package digital.bean.jeecg.dto; + +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.io.Serializable; + +/** + * 文件上传 + * cloud api 用到的接口传输对象 + * @author: smcp + */ +@Data +public class FileUploadDTO implements Serializable { + + private static final long serialVersionUID = -4111953058578954386L; + + private MultipartFile file; + + private String bizPath; + + private String uploadType; + + private String customBucket; + + public FileUploadDTO(){ + + } + + /** + * 简单上传 构造器1 + * @param file + * @param bizPath + * @param uploadType + */ + public FileUploadDTO(MultipartFile file,String bizPath,String uploadType){ + this.file = file; + this.bizPath = bizPath; + this.uploadType = uploadType; + } + + /** + * 申明桶 文件上传 构造器2 + * @param file + * @param bizPath + * @param uploadType + * @param customBucket + */ + public FileUploadDTO(MultipartFile file,String bizPath,String uploadType,String customBucket){ + this.file = file; + this.bizPath = bizPath; + this.uploadType = uploadType; + this.customBucket = customBucket; + } + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/LogDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/LogDTO.java new file mode 100644 index 0000000..d8f8cfb --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/LogDTO.java @@ -0,0 +1,85 @@ +package digital.bean.jeecg.dto; + +import lombok.Data; +import digital.base.vo.LoginUser; + +import java.io.Serializable; +import java.util.Date; + +/** + * 日志对象 + * cloud api 用到的接口传输对象 + * @author: smcp + */ +@Data +public class LogDTO implements Serializable { + + private static final long serialVersionUID = 8482720462943906924L; + + /**内容*/ + private String logContent; + + private String appKey; + + /**日志类型(0:操作日志;1:登录日志;2:定时任务) */ + private Integer logType; + + /**操作类型(1:添加;2:修改;3:删除;) */ + private Integer operateType; + + /**登录用户 */ + private LoginUser loginUser; + + private String id; + private String createBy; + private Date createTime; + private Long costTime; + private String ip; + + /**请求参数 */ + private String requestParam; + + /** + * 请求类型 + */ + private String requestType; + + /** + * 请求路径 + */ + private String requestUrl; + + /** + * 请求方法 + */ + private String method; + + private String result; + + /** + * 操作人用户名称 + */ + private String username; + + /** + * 操作人用户账户 + */ + private String userId; + + public LogDTO() { + + } + + public LogDTO(String logContent, Integer logType, Integer operatetype){ + this.logContent = logContent; + this.logType = logType; + this.operateType = operatetype; + } + + public LogDTO(String logContent, Integer logType, Integer operatetype, LoginUser loginUser){ + this.logContent = logContent; + this.logType = logType; + this.operateType = operatetype; + this.loginUser = loginUser; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/OnlineAuthDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/OnlineAuthDTO.java new file mode 100644 index 0000000..e92108a --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/OnlineAuthDTO.java @@ -0,0 +1,42 @@ +package digital.bean.jeecg.dto; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * online 拦截器权限判断 + * cloud api 用到的接口传输对象 + * @author: smcp + */ +@Data +public class OnlineAuthDTO implements Serializable { + private static final long serialVersionUID = 1771827545416418203L; + + + /** + * 用户名 + */ + private String username; + + /** + * 可能的请求地址 + */ + private List possibleUrl; + + /** + * online开发的菜单地址 + */ + private String onlineFormUrl; + + public OnlineAuthDTO(){ + + } + + public OnlineAuthDTO(String username, List possibleUrl, String onlineFormUrl){ + this.username = username; + this.possibleUrl = possibleUrl; + this.onlineFormUrl = onlineFormUrl; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusMessageDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusMessageDTO.java new file mode 100644 index 0000000..f81710f --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusMessageDTO.java @@ -0,0 +1,44 @@ +package digital.bean.jeecg.dto.message; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 带业务参数的消息 + * @author: smcp + */ +@Data +public class BusMessageDTO extends MessageDTO implements Serializable { + + private static final long serialVersionUID = 9104793287983367669L; + /** + * 业务类型 + */ + private String busType; + + /** + * 业务id + */ + private String busId; + + public BusMessageDTO(){ + + } + + /** + * 构造 带业务参数的消息 + * @param fromUser + * @param toUser + * @param title + * @param msgContent + * @param msgCategory + * @param busType + * @param busId + */ + public BusMessageDTO(String fromUser, String toUser, String title, String msgContent, String msgCategory, String busType, String busId){ + super(fromUser, toUser, title, msgContent, msgCategory); + this.busId = busId; + this.busType = busType; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusTemplateMessageDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusTemplateMessageDTO.java new file mode 100644 index 0000000..fd0bda1 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/BusTemplateMessageDTO.java @@ -0,0 +1,46 @@ +package digital.bean.jeecg.dto.message; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * 带业务参数的模板消息 + * @author: smcp + */ +@Data +public class BusTemplateMessageDTO extends TemplateMessageDTO implements Serializable { + + private static final long serialVersionUID = -4277810906346929459L; + + /** + * 业务类型 + */ + private String busType; + + /** + * 业务id + */ + private String busId; + + public BusTemplateMessageDTO(){ + + } + + /** + * 构造 带业务参数的模板消息 + * @param fromUser + * @param toUser + * @param title + * @param templateParam + * @param templateCode + * @param busType + * @param busId + */ + public BusTemplateMessageDTO(String fromUser, String toUser, String title, Map templateParam, String templateCode, String busType, String busId){ + super(fromUser, toUser, title, templateParam, templateCode); + this.busId = busId; + this.busType = busType; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/MessageDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/MessageDTO.java new file mode 100644 index 0000000..670c822 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/MessageDTO.java @@ -0,0 +1,75 @@ +package digital.bean.jeecg.dto.message; + +import lombok.Data; +import digital.base.constant.CommonConstant; + +import java.io.Serializable; + +/** + * 普通消息 + * @author: smcp + */ +@Data +public class MessageDTO implements Serializable { + + private static final long serialVersionUID = -5690444483968058442L; + + /** + * 发送人(用户登录账户) + */ + protected String fromUser; + + /** + * 发送给(用户登录账户) + */ + protected String toUser; + + /** + * 发送给所有人 + */ + protected Boolean toAll; + + /** + * 消息主题 + */ + protected String title; + + /** + * 消息内容 + */ + protected String content; + + /** + * 消息类型 1:消息 2:系统消息 + */ + protected String category; + + + public MessageDTO(){ + + } + + /** + * 构造器1 系统消息 + */ + public MessageDTO(String fromUser,String toUser,String title, String content){ + this.fromUser = fromUser; + this.toUser = toUser; + this.title = title; + this.content = content; + //默认 都是2系统消息 + this.category = CommonConstant.MSG_CATEGORY_2; + } + + /** + * 构造器2 支持设置category 1:消息 2:系统消息 + */ + public MessageDTO(String fromUser,String toUser,String title, String content, String category){ + this.fromUser = fromUser; + this.toUser = toUser; + this.title = title; + this.content = content; + this.category = category; + } + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateDTO.java new file mode 100644 index 0000000..1ba036f --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateDTO.java @@ -0,0 +1,38 @@ +package digital.bean.jeecg.dto.message; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * 消息模板dto + * @author: smcp + */ +@Data +public class TemplateDTO implements Serializable { + + private static final long serialVersionUID = 5848247133907528650L; + + /** + * 模板编码 + */ + protected String templateCode; + + /** + * 模板参数 + */ + protected Map templateParam; + + /** + * 构造器 通过设置模板参数和模板编码 作为参数获取消息内容 + */ + public TemplateDTO(String templateCode, Map templateParam){ + this.templateCode = templateCode; + this.templateParam = templateParam; + } + + public TemplateDTO(){ + + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateMessageDTO.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateMessageDTO.java new file mode 100644 index 0000000..947c607 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/dto/message/TemplateMessageDTO.java @@ -0,0 +1,50 @@ +package digital.bean.jeecg.dto.message; + +import lombok.Data; + +import java.io.Serializable; +import java.util.Map; + +/** + * 模板消息 + * @author: smcp + */ +@Data +public class TemplateMessageDTO extends TemplateDTO implements Serializable { + + private static final long serialVersionUID = 411137565170647585L; + + + /** + * 发送人(用户登录账户) + */ + protected String fromUser; + + /** + * 发送给(用户登录账户) + */ + protected String toUser; + + /** + * 消息主题 + */ + protected String title; + + + public TemplateMessageDTO(){ + + } + + /** + * 构造器1 发模板消息用 + */ + public TemplateMessageDTO(String fromUser, String toUser,String title, Map templateParam, String templateCode){ + super(templateCode, templateParam); + this.fromUser = fromUser; + this.toUser = toUser; + this.title = title; + } + + + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/entity/JeecgEntity.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/entity/JeecgEntity.java new file mode 100644 index 0000000..639ee1d --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/entity/JeecgEntity.java @@ -0,0 +1,66 @@ +package digital.bean.jeecg.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: Entity基类 + * @Author: dangzhenghui@163.com + * @Date: 2019-4-28 + * @Version: 1.1 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class JeecgEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "ID") + private java.lang.String id; + + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + @Excel(name = "创建人", width = 15) + private java.lang.String createBy; + + /** + * 创建时间 + */ + @ApiModelProperty(value = "创建时间") + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + @Excel(name = "更新人", width = 15) + private java.lang.String updateBy; + + /** + * 更新时间 + */ + @ApiModelProperty(value = "更新时间") + @Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/ComboModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/ComboModel.java new file mode 100644 index 0000000..b69d589 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/ComboModel.java @@ -0,0 +1,52 @@ +package digital.bean.jeecg.vo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Description: 文档管理 + * @author: smcp + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@JsonIgnoreProperties(ignoreUnknown = true) +public class ComboModel implements Serializable { + private String id; + private String title; + /** + * 文档管理 表单table默认选中 + */ + private boolean checked; + /** + * 文档管理 表单table 用户账号 + */ + private String username; + /** + * 文档管理 表单table 用户邮箱 + */ + private String email; + /** + * 文档管理 表单table 角色编码 + */ + private String roleCode; + + public ComboModel() { + + } + + ; + + public ComboModel(String id, String title, boolean checked, String username) { + this.id = id; + this.title = title; + this.checked = false; + this.username = username; + } + + ; +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModel.java new file mode 100644 index 0000000..51fb21e --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModel.java @@ -0,0 +1,53 @@ +package digital.bean.jeecg.vo; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + * @Description: 字典类 + * @author: smcp + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@JsonIgnoreProperties(ignoreUnknown = true) +public class DictModel implements Serializable { + private static final long serialVersionUID = 1L; + /** + * 字典value + */ + private String value; + /** + * 字典文本 + */ + private String text; + + public DictModel() { + } + + public DictModel(String value, String text) { + this.value = value; + this.text = text; + } + + /** + * 特殊用途: JgEditableTable + * + * @return + */ + public String getTitle() { + return this.text; + } + + /** + * 特殊用途: vue3 Select组件 + */ + public String getLabel() { + return this.text; + } + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModelMany.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModelMany.java new file mode 100644 index 0000000..a149132 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictModelMany.java @@ -0,0 +1,20 @@ +package digital.bean.jeecg.vo; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +/** + * 查询多个字典时用到 + * + * @author: smcp + */ +@Data +@EqualsAndHashCode(callSuper = true) +public class DictModelMany extends DictModel { + + /** + * 字典code,根据多个字段code查询时才用到,用于区分不同的字典选项 + */ + private String dictCode; + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictQuery.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictQuery.java new file mode 100644 index 0000000..9779a79 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DictQuery.java @@ -0,0 +1,36 @@ +package digital.bean.jeecg.vo; + +import lombok.Data; + +/** + * 字典查询参数实体 + * + * @author: smcp + */ +@Data +public class DictQuery { + /** + * 表名 + */ + private String table; + /** + * 存储列 + */ + private String code; + + /** + * 显示列 + */ + private String text; + + /** + * 关键字查询 + */ + private String keyword; + + /** + * 存储列的值 用于回显查询 + */ + private String codeValue; + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DynamicDataSourceModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DynamicDataSourceModel.java new file mode 100644 index 0000000..5053d59 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/DynamicDataSourceModel.java @@ -0,0 +1,57 @@ +package digital.bean.jeecg.vo; + +import lombok.Data; +import org.springframework.beans.BeanUtils; + +/** + * @Description: 数据源 + * @author: smcp + */ +@Data +public class DynamicDataSourceModel { + + /** + * id + */ + private java.lang.String id; + /** + * 数据源编码 + */ + private java.lang.String code; + /** + * 数据库类型 + */ + private java.lang.String dbType; + /** + * 驱动类 + */ + private java.lang.String dbDriver; + /** + * 数据源地址 + */ + private java.lang.String dbUrl; + /** + * 用户名 + */ + private java.lang.String dbUsername; + /** + * 密码 + */ + private java.lang.String dbPassword; + +// /** +// * 数据库名称 +// */ +// private java.lang.String dbName; + + public DynamicDataSourceModel() { + + } + + public DynamicDataSourceModel(Object dbSource) { + if (dbSource != null) { + BeanUtils.copyProperties(dbSource, this); + } + } + +} \ No newline at end of file diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SelectTreeModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SelectTreeModel.java new file mode 100644 index 0000000..1854845 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SelectTreeModel.java @@ -0,0 +1,32 @@ +package digital.bean.jeecg.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * 下拉树 model + * + * @author jeecg-boot + */ +@Data +public class SelectTreeModel implements Serializable { + + private String key; + private String title; + private String value; + /** + * 父Id + */ + private String parentId; + /** + * 是否是叶节点 + */ + private boolean isLeaf; + /** + * 子节点 + */ + private List children; + +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysCategoryModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysCategoryModel.java new file mode 100644 index 0000000..6a97823 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysCategoryModel.java @@ -0,0 +1,58 @@ +package digital.bean.jeecg.vo; + +/** + * @Author qinfeng + * @Date 2020/2/19 12:01 + * @Description: + * @Version 1.0 + */ +public class SysCategoryModel { + /** + * 主键 + */ + private java.lang.String id; + /** + * 父级节点 + */ + private java.lang.String pid; + /** + * 类型名称 + */ + private java.lang.String name; + /** + * 类型编码 + */ + private java.lang.String code; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getPid() { + return pid; + } + + public void setPid(String pid) { + this.pid = pid; + } + + 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; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysDepartModel.java b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysDepartModel.java new file mode 100644 index 0000000..8a77027 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/jeecg/vo/SysDepartModel.java @@ -0,0 +1,177 @@ +package digital.bean.jeecg.vo; + +/** + * 部门机构model + * + * @author: lvdandan + */ +public class SysDepartModel { + /** + * ID + */ + private String id; + /** + * 父机构ID + */ + private String parentId; + /** + * 机构/部门名称 + */ + private String departName; + /** + * 英文名 + */ + private String departNameEn; + /** + * 缩写 + */ + private String departNameAbbr; + /** + * 排序 + */ + private Integer departOrder; + /** + * 描述 + */ + private String description; + /** + * 机构类别 1组织机构,2岗位 + */ + private String orgCategory; + /** + * 机构类型 + */ + private String orgType; + /** + * 机构编码 + */ + private String orgCode; + /** + * 手机号 + */ + private String mobile; + /** + * 传真 + */ + private String fax; + /** + * 地址 + */ + private String address; + /** + * 备注 + */ + private String memo; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getDepartName() { + return departName; + } + + public void setDepartName(String departName) { + this.departName = departName; + } + + public String getDepartNameEn() { + return departNameEn; + } + + public void setDepartNameEn(String departNameEn) { + this.departNameEn = departNameEn; + } + + public String getDepartNameAbbr() { + return departNameAbbr; + } + + public void setDepartNameAbbr(String departNameAbbr) { + this.departNameAbbr = departNameAbbr; + } + + public Integer getDepartOrder() { + return departOrder; + } + + public void setDepartOrder(Integer departOrder) { + this.departOrder = departOrder; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getOrgCategory() { + return orgCategory; + } + + public void setOrgCategory(String orgCategory) { + this.orgCategory = orgCategory; + } + + public String getOrgType() { + return orgType; + } + + public void setOrgType(String orgType) { + this.orgType = orgType; + } + + public String getOrgCode() { + return orgCode; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getFax() { + return fax; + } + + public void setFax(String fax) { + this.fax = fax; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getMemo() { + return memo; + } + + public void setMemo(String memo) { + this.memo = memo; + } +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/task/DpUser.java b/digital-common/digital-bean/src/main/java/digital/bean/task/DpUser.java new file mode 100644 index 0000000..2974c00 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/task/DpUser.java @@ -0,0 +1,249 @@ +package digital.bean.task; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: dp_user + * @Author: jeecg-boot + * @Date: 2024-04-17 + * @Version: V1.0 + */ +@Data +@TableName("dp_user") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "dp_user对象", description = "dp_user") +public class DpUser implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键id") + private String id; + + @ApiModelProperty(value = "appId") + private String appId; + + @ApiModelProperty(value = "roleType") + private String roleType; + + @ApiModelProperty(value = "apiAuthority") + private boolean apiAuthority; + + @ApiModelProperty(value = "appSecret") + private String appSecret; + + @ApiModelProperty(value = "直销客户传C ,代理商传D") + private String reqFrom; + + @ApiModelProperty(value = "token") + private String token; + + @ApiModelProperty(value = "token 过期时间") + private Date expires; + + @ApiModelProperty(value = "登录账号") + private String account; + /** + * 真实姓名 + */ + @Excel(name = "真实姓名", width = 15) + @ApiModelProperty(value = "真实姓名") + private String realname; + /** + * 密码 + */ + @Excel(name = "密码", width = 15) + @ApiModelProperty(value = "密码") + private String password; + /** + * md5密码盐 + */ + @Excel(name = "md5密码盐", width = 15) + @ApiModelProperty(value = "md5密码盐") + private String salt; + /** + * 头像 + */ + @Excel(name = "头像", width = 15) + @ApiModelProperty(value = "头像") + private String avatar; + /** + * 生日 + */ + @Excel(name = "生日", width = 15, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "生日") + private Date birthday; + /** + * 性别(0-默认未知,1-男,2-女) + */ + @Excel(name = "性别(0-默认未知,1-男,2-女)", width = 15) + @ApiModelProperty(value = "性别(0-默认未知,1-男,2-女)") + private String sex; + /** + * 电子邮件 + */ + @Excel(name = "电子邮件", width = 15) + @ApiModelProperty(value = "电子邮件") + private String email; + /** + * 电话 + */ + @Excel(name = "电话", width = 15) + @ApiModelProperty(value = "电话") + private String phone; + /** + * 性别(1-正常,2-冻结) + */ + @Excel(name = "性别(1-正常,2-冻结)", width = 15) + @ApiModelProperty(value = "性别(1-正常,2-冻结)") + private String status; + /** + * 删除状态(0-正常,1-已删除) + */ + @Excel(name = "删除状态(0-正常,1-已删除)", width = 15) + @ApiModelProperty(value = "删除状态(0-正常,1-已删除)") + @TableLogic + private Integer delFlag; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "创建时间") + private Date createTime; + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + @ApiModelProperty(value = "更新时间") + private Date updateTime; + + /** + * 公司名称 + */ + @Excel(name = "公司名称", width = 15) + @ApiModelProperty(value = "公司名称") + private String companyName; + /** + * 购买的短视频合成时长 + */ + @Excel(name = "购买的短视频合成时长", width = 15) + @ApiModelProperty(value = "购买的短视频合成时长") + private Integer videoComposeTime; + /** + * 购买的数字人个数 + */ + @Excel(name = "购买的数字人个数", width = 15) + @ApiModelProperty(value = "购买的数字人个数") + private Integer modelNum; + + @Excel(name = "使用的数字人个数", width = 15) + @ApiModelProperty(value = "使用的数字人个数") + private Integer useModelNum; + /** + * 购买克隆声音数 + */ + @Excel(name = "购买克隆声音数", width = 15) + @ApiModelProperty(value = "购买克隆声音数") + private Integer cloneSoundNum; + /** + * 定制的数字人个数 + */ + @Excel(name = "定制的数字人个数", width = 15) + @ApiModelProperty(value = "定制的数字人个数") + private Integer customizedModelNum; + /** + * 剩余的数字人个数 + */ + @Excel(name = "剩余的数字人个数", width = 15) + @ApiModelProperty(value = "剩余的数字人个数") + private Integer remainModelNum; + /** + * 剩余声音克隆个数 + */ + @Excel(name = "剩余声音克隆个数", width = 15) + @ApiModelProperty(value = "剩余声音克隆个数") + private Integer remainCloneSoundNum; + /** + * remainComposeTime + */ + @Excel(name = "remainComposeTime", width = 15) + @ApiModelProperty(value = "remainComposeTime") + private Integer remainComposeTime; + /** + * 短视频合成时长 分 + */ + @Excel(name = "短视频合成时长 分", width = 15) + @ApiModelProperty(value = "短视频合成时长 分") + private Integer videoComposeMin; + /** + * 短视频合成时长 秒 + */ + @Excel(name = "短视频合成时长 秒", width = 15) + @ApiModelProperty(value = "短视频合成时长 秒") + private Integer videoComposeSec; + /** + * 剩余定制模特数-豪华版(2K) + */ + @Excel(name = "剩余定制模特数-豪华版(2K)", width = 15) + @ApiModelProperty(value = "剩余定制模特数-豪华版(2K)") + private Integer remainModeTwoNum; + /** + * 剩余定制模特数-旗舰版(4K) + */ + @Excel(name = "剩余定制模特数-旗舰版(4K)", width = 15) + @ApiModelProperty(value = "剩余定制模特数-旗舰版(4K)") + private Integer remainModeThreeNum; + /** + * 剩余克隆声音数-基础版 + */ + @Excel(name = "剩余克隆声音数-基础版", width = 15) + @ApiModelProperty(value = "剩余克隆声音数-基础版") + private Integer remainSoundTwoNum; + /** + * 剩余克隆声音数-情感版 + */ + @Excel(name = "剩余克隆声音数-情感版", width = 15) + @ApiModelProperty(value = "剩余克隆声音数-情感版") + private Integer remainSoundThreeNum; + /** + * 互动并发总数量 + */ + @Excel(name = "互动并发总数量", width = 15) + @ApiModelProperty(value = "互动并发总数量") + private Integer liveInteractConcurrency; + /** + * 直播并发总数量 + */ + @Excel(name = "直播并发总数量", width = 15) + @ApiModelProperty(value = "直播并发总数量") + private Integer liveConcurrency; +} diff --git a/digital-common/digital-bean/src/main/java/digital/bean/task/MwTrainTask.java b/digital-common/digital-bean/src/main/java/digital/bean/task/MwTrainTask.java new file mode 100644 index 0000000..f9fd228 --- /dev/null +++ b/digital-common/digital-bean/src/main/java/digital/bean/task/MwTrainTask.java @@ -0,0 +1,81 @@ +package digital.bean.task; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +@Data +@TableName("mw_train_task") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "mw_train_task对象", description = "mw_train_task") +public class MwTrainTask implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private String id; + + @ApiModelProperty(value = "训练时长") + private Integer costTime; + + @ApiModelProperty(value = "任务id") + private String taskId; + + @ApiModelProperty(value = "试穿类型 单个single 还是批量 batch ") + private String tryOnType; + + @ApiModelProperty(value = "试穿算法 cloth 衣服 hair 发型 ") + private String tryOnAlgo; + + @ApiModelProperty(value = "用户id") + private String userId; + + @ApiModelProperty(value = "服装路径") + private String clothPath; + + @ApiModelProperty(value = "模特路径") + private String modelPath; + + @ApiModelProperty(value = "平铺图") + private String tilePath; + + @ApiModelProperty(value = "状态") + private String status; + + @ApiModelProperty(value = "结果成功还是失败") + private String result; + + @ApiModelProperty(value = "请求结果") + private String requestResult; + + @ApiModelProperty(value = "回调结果图片url") + private String resultImages; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "createdAt") + private Date createTime; + + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "updatedAt") + private Date updateTime; + + @ApiModelProperty(value = "删除标识(0-未删除,1-已删除)") + @TableLogic + private Integer delFlag; + +} diff --git a/digital-common/digital-config/pom.xml b/digital-common/digital-config/pom.xml new file mode 100644 index 0000000..5570cf0 --- /dev/null +++ b/digital-common/digital-config/pom.xml @@ -0,0 +1,232 @@ + + + + digital-common + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-config + + + 8 + 8 + + + + + + org.jeecgframework.boot + jeecg-boot-base-tools + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.boot + spring-boot-starter-mail + + + org.springframework.boot + spring-boot-starter-aop + + + org.springframework.boot + spring-boot-starter-actuator + + + + + + + + + io.micrometer + micrometer-registry-prometheus + + + + + commons-io + commons-io + ${commons.version} + + + commons-lang + commons-lang + ${commons.version} + + + + org.springframework.boot + spring-boot-starter-freemarker + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + + + com.alibaba + druid-spring-boot-starter + ${druid.version} + + + + + com.baomidou + dynamic-datasource-spring-boot-starter + ${dynamic-datasource-spring-boot-starter.version} + + + + + + mysql + mysql-connector-java + ${mysql-connector-java.version} + runtime + + + + com.microsoft.sqlserver + sqljdbc4 + ${sqljdbc4.version} + runtime + + + + com.oracle + ojdbc6 + ${ojdbc6.version} + runtime + + + + org.postgresql + postgresql + ${postgresql.version} + runtime + + + + + com.auth0 + java-jwt + ${java-jwt.version} + + + + + org.apache.shiro + shiro-spring-boot-starter + ${shiro.version} + + + + org.crazycake + shiro-redis + ${shiro-redis.version} + + + org.apache.shiro + shiro-core + + + + com.puppycrawl.tools + checkstyle + + + + + + + com.github.xiaoymin + knife4j-spring-boot-starter + ${knife4j-spring-boot-starter.version} + + + + + + org.jeecgframework.boot + codegenerate + ${codegenerate.version} + + + + + org.jeecgframework + autopoi-web + ${autopoi-web.version} + + + commons-codec + commons-codec + + + + + + + io.minio + minio + + + com.google.guava + guava + ${guava.version} + + + + + com.aliyun + aliyun-java-sdk-dysmsapi + ${aliyun-java-sdk-dysmsapi.version} + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + + + + + com.fasterxml.jackson.module + jackson-module-kotlin + + + org.jeecgframework.boot + digital-base + 3.2.0 + compile + + + org.jeecgframework.boot + digital-util + 3.2.0 + compile + + + com.github.xiaoymin + swagger-bootstrap-ui + 1.9.6 + + + \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/AutoPoiConfig.java b/digital-common/digital-config/src/main/java/digital/config/AutoPoiConfig.java new file mode 100644 index 0000000..ed3415d --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/AutoPoiConfig.java @@ -0,0 +1,28 @@ +package digital.config; + +import org.jeecgframework.core.util.ApplicationContextUtil; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * @Author: Scott + * @Date: 2018/2/7 + * @description: autopoi 配置类 + */ + +@Configuration +public class AutoPoiConfig { + + /** + * excel注解字典参数支持(导入导出字典值,自动翻译) + * 举例: @Excel(name = "性别", width = 15, dicCode = "sex") + * 1、导出的时候会根据字典配置,把值1,2翻译成:男、女; + * 2、导入的时候,会把男、女翻译成1,2存进数据库; + * @return + */ + @Bean + public ApplicationContextUtil applicationContextUtil() { + return new org.jeecgframework.core.util.ApplicationContextUtil(); + } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/CommonConfig.java b/digital-common/digital-config/src/main/java/digital/config/CommonConfig.java new file mode 100644 index 0000000..b4aa7b5 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/CommonConfig.java @@ -0,0 +1,28 @@ +package digital.config; + +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import digital.util.util.SpringContextHolder; + +/** + * SpringContextHolder注册用 + * + * @author: scott + * @date: 2020/01/01 16:00 + */ +@Configuration +public class CommonConfig { + + /** + * Spring上下文工具配置 + * + * @return + */ + @Bean + @ConditionalOnMissingBean(SpringContextHolder.class) + public SpringContextHolder springContextHolder() { + SpringContextHolder holder = new SpringContextHolder(); + return holder; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/CorsFilterCondition.java b/digital-common/digital-config/src/main/java/digital/config/CorsFilterCondition.java new file mode 100644 index 0000000..e6e5b31 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/CorsFilterCondition.java @@ -0,0 +1,25 @@ +package digital.config; + + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; +import digital.base.constant.CommonConstant; + + +/** + * 跨域配置加载条件 + * @author: smcp + */ +public class CorsFilterCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + Object object = context.getEnvironment().getProperty(CommonConstant.CLOUD_SERVER_KEY); + //如果没有服务注册发现的配置 说明是单体应用 则加载跨域配置 返回true + if(object==null){ + return true; + } + return false; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/DruidConfig.java b/digital-common/digital-config/src/main/java/digital/config/DruidConfig.java new file mode 100644 index 0000000..411f6d7 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/DruidConfig.java @@ -0,0 +1,85 @@ +package digital.config; + +import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; +import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties; +import com.alibaba.druid.util.Utils; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.*; +import java.io.IOException; + +/** + * @Description: DruidConfig配置类 + * @author: smcp + */ +@Configuration +@AutoConfigureAfter(DruidDataSourceAutoConfigure.class) +public class DruidConfig { + + /** + * 带有广告的common.js全路径,druid-1.1.14 + */ + private static final String FILE_PATH = "support/http/resources/js/common.js"; + /** + * 原始脚本,触发构建广告的语句 + */ + private static final String ORIGIN_JS = "this.buildFooter();"; + /** + * 替换后的脚本 + */ + private static final String NEW_JS = "//this.buildFooter();"; + + /** + * 去除Druid监控页面的广告 + * + * @param properties DruidStatProperties属性集合 + * @return {@link FilterRegistrationBean} + */ + @Bean + @ConditionalOnWebApplication + @ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true") + public FilterRegistrationBean removeDruidAdFilter( + DruidStatProperties properties) throws IOException { + // 获取web监控页面的参数 + DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); + // 提取common.js的配置路径 + String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*"; + String commonJsPattern = pattern.replaceAll("\\*", "js/common.js"); + // 获取common.js + String text = Utils.readFromResource(FILE_PATH); + // 屏蔽 this.buildFooter(); 不构建广告 + final String newJs = text.replace(ORIGIN_JS, NEW_JS); + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setFilter(new RemoveAdFilter(newJs)); + registration.addUrlPatterns(commonJsPattern); + return registration; + } + + /** + * 删除druid的广告过滤器 + * + * @author BBF + */ + private class RemoveAdFilter implements Filter { + + private final String newJs; + + public RemoveAdFilter(String newJs) { + this.newJs = newJs; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + chain.doFilter(request, response); + // 重置缓冲区,响应头不会被重置 + response.resetBuffer(); + response.getWriter().write(newJs); + } + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/JeecgBaseConfig.java b/digital-common/digital-config/src/main/java/digital/config/JeecgBaseConfig.java new file mode 100644 index 0000000..5b90502 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/JeecgBaseConfig.java @@ -0,0 +1,52 @@ +package digital.config; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; +import digital.config.vo.Shiro; + + +/** + * 加载项目配置 + * @author: smcp + */ +@Component("jeecgBaseConfig") +@ConfigurationProperties(prefix = "jeecg") +public class JeecgBaseConfig { + /** + * 是否启用安全模式 + */ + private Boolean safeMode = false; + /** + * shiro拦截排除 + */ + private Shiro shiro; + /** + * 签名密钥串(字典等敏感接口) + * @TODO 降低使用成本加的默认值,实际以 yml配置 为准 + */ + private String signatureSecret = "dd05f1c54d63749eda95f9fa6d49v442a"; + + public Boolean getSafeMode() { + return safeMode; + } + + public void setSafeMode(Boolean safeMode) { + this.safeMode = safeMode; + } + + public String getSignatureSecret() { + return signatureSecret; + } + + public void setSignatureSecret(String signatureSecret) { + this.signatureSecret = signatureSecret; + } + + public Shiro getShiro() { + return shiro; + } + + public void setShiro(Shiro shiro) { + this.shiro = shiro; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/JeecgCloudCondition.java b/digital-common/digital-config/src/main/java/digital/config/JeecgCloudCondition.java new file mode 100644 index 0000000..3593a56 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/JeecgCloudCondition.java @@ -0,0 +1,25 @@ +package digital.config; + + +import org.springframework.context.annotation.Condition; +import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.type.AnnotatedTypeMetadata; +import digital.base.constant.CommonConstant; + + +/** + * 微服务环境加载条件 + * @author: smcp + */ +public class JeecgCloudCondition implements Condition { + + @Override + public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { + Object object = context.getEnvironment().getProperty(CommonConstant.CLOUD_SERVER_KEY); + //如果没有服务注册发现的配置 说明是单体应用 + if(object==null){ + return false; + } + return true; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/MyLocaleResolver.java b/digital-common/digital-config/src/main/java/digital/config/MyLocaleResolver.java new file mode 100644 index 0000000..baf9089 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/MyLocaleResolver.java @@ -0,0 +1,31 @@ +package digital.config; + +import org.springframework.web.servlet.LocaleResolver; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Locale; + +/** + * author: damao + * date:2022-09-15 11:54 + * description: + **/ +public class MyLocaleResolver implements LocaleResolver { + @Override + public Locale resolveLocale(HttpServletRequest req) { + //获取请求中的参数链接 + String language = req.getHeader("langType");//前端传递的参数用来判断中文还是英文 + Locale locale = Locale.getDefault();//获取默认Locale + if (!oConvertUtils.isEmpty(language)) {//判断传递参数是否为空 + locale = new Locale(language); + } + return locale; + } + + @Override + public void setLocale(HttpServletRequest request, HttpServletResponse response, Locale locale) { + + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/RestTemplateConfig.java b/digital-common/digital-config/src/main/java/digital/config/RestTemplateConfig.java new file mode 100644 index 0000000..5c69005 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/RestTemplateConfig.java @@ -0,0 +1,31 @@ +package digital.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +/** +* 优雅的http请求方式RestTemplate +* @author: smcp +* @Return: +*/ +@Configuration +public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate(ClientHttpRequestFactory factory) { + return new RestTemplate(factory); + } + + @Bean + public ClientHttpRequestFactory simpleClientHttpRequestFactory() { + SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory(); + //ms毫秒 + factory.setReadTimeout(7200*1000); + //ms毫秒 + factory.setConnectTimeout(7200*1000); + return factory; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/StaticConfig.java b/digital-common/digital-config/src/main/java/digital/config/StaticConfig.java new file mode 100644 index 0000000..686b171 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/StaticConfig.java @@ -0,0 +1,38 @@ +//package digital.config; +// +//import lombok.Data; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.stereotype.Component; +// +///** +// * 设置静态参数初始化 +// * @author: smcp +// */ +//@Component +//@Data +//public class StaticConfig { +// +// @Value("${jeecg.oss.accessKey}") +// private String accessKeyId; +// +// @Value("${jeecg.oss.secretKey}") +// private String accessKeySecret; +// +// @Value(value = "${spring.mail.username}") +// private String emailFrom; +// +//// /** +//// * 签名密钥串 +//// */ +//// @Value(value = "${jeecg.signatureSecret}") +//// private String signatureSecret; +// +// +// /*@Bean +// public void initStatic() { +// DySmsHelper.setAccessKeyId(accessKeyId); +// DySmsHelper.setAccessKeySecret(accessKeySecret); +// EmailSendMsgHandle.setEmailFrom(emailFrom); +// }*/ +// +//} diff --git a/digital-common/digital-config/src/main/java/digital/config/Swagger2Config.java b/digital-common/digital-config/src/main/java/digital/config/Swagger2Config.java new file mode 100644 index 0000000..e508a10 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/Swagger2Config.java @@ -0,0 +1,184 @@ +package digital.config; + +import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j; +import io.swagger.annotations.ApiOperation; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.util.ReflectionUtils; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping; +import digital.base.constant.CommonConstant; +import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.*; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.spring.web.plugins.WebFluxRequestHandlerProvider; +import springfox.documentation.spring.web.plugins.WebMvcRequestHandlerProvider; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @Author scott + */ +@Configuration +@EnableSwagger2 //开启 Swagger2 +@EnableKnife4j //开启 knife4j,可以不写 +@Import(BeanValidatorPluginsConfiguration.class) +public class Swagger2Config implements WebMvcConfigurer { + + /** + * 解决springboot2.6 和springfox不兼容问题 + * @return + */ + @Bean + public static BeanPostProcessor springfoxHandlerProviderBeanPostProcessor() { + return new BeanPostProcessor() { + + @Override + public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + if (bean instanceof WebMvcRequestHandlerProvider || bean instanceof WebFluxRequestHandlerProvider) { + customizeSpringfoxHandlerMappings(getHandlerMappings(bean)); + } + return bean; + } + + private void customizeSpringfoxHandlerMappings(List mappings) { + List copy = mappings.stream() + .filter(mapping -> mapping.getPatternParser() == null) + .collect(Collectors.toList()); + mappings.clear(); + mappings.addAll(copy); + } + + @SuppressWarnings("unchecked") + private List getHandlerMappings(Object bean) { + try { + Field field = ReflectionUtils.findField(bean.getClass(), "handlerMappings"); + field.setAccessible(true); + return (List) field.get(bean); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new IllegalStateException(e); + } + } + }; + } + + /** + * + * 显示swagger-ui.html文档展示页,还必须注入swagger资源: + * + * @param registry + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/"); + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); + } + + /** + * swagger2的配置文件,这里可以配置swagger2的一些基本的内容,比如扫描的包等等 + * + * @return Docket + */ + + @Bean(value = "digital-application") + public Docket zitaApplication() { + return new Docket(DocumentationType.SWAGGER_2) + .apiInfo(apiInfo()).groupName("换装服务") + .select() + //此包路径下的类,才生成接口文档 + .apis(RequestHandlerSelectors.basePackage("digital.application")) + //加了ApiOperation注解的类,才生成接口文档 + .apis(RequestHandlerSelectors.withClassAnnotation(RestController.class)) + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + .paths(PathSelectors.any()) + .build() + .securitySchemes(Collections.singletonList(securityScheme())) + .securityContexts(securityContexts()); + //.globalOperationParameters(setHeaderToken()); + } + + /*** + * oauth2配置 + * 需要增加swagger授权回调地址 + * http://localhost:8888/webjars/springfox-swagger-ui/o2c.html + * @return + */ + @Bean + SecurityScheme securityScheme() { + return new ApiKey(CommonConstant.X_ACCESS_TOKEN, CommonConstant.X_ACCESS_TOKEN, "header"); + } + + /** + * JWT token + * @return + */ + private List setHeaderToken() { + ParameterBuilder tokenPar = new ParameterBuilder(); + List pars = new ArrayList<>(); + tokenPar.name(CommonConstant.X_ACCESS_TOKEN).description("token").modelRef(new ModelRef("string")).parameterType("header").required(false).build(); + pars.add(tokenPar.build()); + return pars; + } + + /** + * api文档的详细信息函数,注意这里的注解引用的是哪个 + * + * @return + */ + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + // //大标题 + .title("换装体验API接口文档") + // 版本号 + .version("1.0") +// .termsOfServiceUrl("NO terms of service") + // 描述 + .description("后台API接口") + // 作者 + .contact(new Contact("zita", "", "")) + // .contact("JEECG团队") + .license("The Apache License, Version 2.0") + .licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html") + .build(); + } + + /** + * 新增 securityContexts 保持登录状态 + */ + private List securityContexts() { + return new ArrayList( + Collections.singleton(SecurityContext.builder() + .securityReferences(defaultAuth()) + .forPaths(PathSelectors.regex("^(?!auth).*$")) + .build()) + ); + } + + private List defaultAuth() { + AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); + AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; + authorizationScopes[0] = authorizationScope; + return new ArrayList( + Collections.singleton(new SecurityReference(CommonConstant.X_ACCESS_TOKEN, authorizationScopes))); + } + + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/ThreadPoolConfiguration.java b/digital-common/digital-config/src/main/java/digital/config/ThreadPoolConfiguration.java new file mode 100644 index 0000000..db4302e --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/ThreadPoolConfiguration.java @@ -0,0 +1,23 @@ +package digital.config; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +@Configuration +@Slf4j +public class ThreadPoolConfiguration { + + @Bean(name = "defaultThreadPoolExecutor", destroyMethod = "shutdown") + public ThreadPoolExecutor systemCheckPoolExecutorService() { + + return new ThreadPoolExecutor(3, 10, 60, TimeUnit.SECONDS, + new LinkedBlockingQueue(10000), + new ThreadFactoryBuilder().setNameFormat("default-executor-%d").build(), + (r, executor) -> log.error("system pool is full! ")); + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/WebMvcConfiguration.java b/digital-common/digital-config/src/main/java/digital/config/WebMvcConfiguration.java new file mode 100644 index 0000000..e7d3104 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/WebMvcConfiguration.java @@ -0,0 +1,157 @@ +package digital.config; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.beans.factory.config.BeanPostProcessor; +//import org.springframework.boot.actuate.trace.http.InMemoryHttpTraceRepository; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Conditional; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; +import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.LocalTime; +import java.time.format.DateTimeFormatter; +import java.util.List; + +/** + * Spring Boot 2.0 解决跨域问题 + * + * @Author qinfeng + * + */ +@Configuration +public class WebMvcConfiguration implements WebMvcConfigurer { + + @Value("${jeecg.path.upload}") + private String upLoadPath; + @Value("${jeecg.path.webapp}") + private String webAppPath; + @Value("${spring.resource.static-locations}") + private String staticLocations; + + @Autowired(required = false) + private PrometheusMeterRegistry prometheusMeterRegistry; + + /** + * 国际化配置 + */ + @Bean + public LocaleResolver localeResolver(){ + return new MyLocaleResolver(); + } + + /** + * 静态资源的配置 - 使得可以从磁盘中读取 Html、图片、视频、音频等 + */ + @Override + public void addResourceHandlers(ResourceHandlerRegistry registry) { + registry.addResourceHandler("/**") + //update-begin-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126 + .addResourceLocations("file:" + upLoadPath + "//") + .addResourceLocations("file:" + webAppPath + "//") + //update-end-author:taoyan date:20211116 for: jeecg.path.webapp配置无效 #3126 + .addResourceLocations(staticLocations.split(",")); + } + + /** + * 方案一: 默认访问根路径跳转 doc.html页面 (swagger文档页面) + * 方案二: 访问根路径改成跳转 index.html页面 (简化部署方案: 可以把前端打包直接放到项目的 webapp,上面的配置) + */ + @Override + public void addViewControllers(ViewControllerRegistry registry) { + registry.addViewController("/").setViewName("doc.html"); + } + + @Bean + @Conditional(CorsFilterCondition.class) + public CorsFilter corsFilter() { + final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource(); + final CorsConfiguration corsConfiguration = new CorsConfiguration(); + //是否允许请求带有验证信息 + corsConfiguration.setAllowCredentials(true); + // 允许访问的客户端域名 + corsConfiguration.addAllowedOriginPattern("*"); + // 允许服务端访问的客户端请求头 + corsConfiguration.addAllowedHeader("*"); + // 允许访问的方法名,GET POST等 + corsConfiguration.addAllowedMethod("*"); + urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration); + return new CorsFilter(urlBasedCorsConfigurationSource); + } + @Override + public void configureMessageConverters(List> converters) { + MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(objectMapper()); + converters.add(jackson2HttpMessageConverter); + } + + /** + * 自定义ObjectMapper + */ + @Bean + @Primary + public ObjectMapper objectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + //处理bigDecimal + objectMapper.enable(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN); + objectMapper.enable(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS); + //处理失败 + objectMapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false); + objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES, false); + //默认的处理日期时间格式 + objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); + JavaTimeModule javaTimeModule = new JavaTimeModule(); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); + javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd"))); + javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss"))); + objectMapper.registerModule(javaTimeModule); + return objectMapper; + } + + /** + * SpringBootAdmin的Httptrace不见了 + * https://blog.csdn.net/u013810234/article/details/110097201 + */ +// @Bean +// public InMemoryHttpTraceRepository getInMemoryHttpTrace(){ +// return new InMemoryHttpTraceRepository(); +// } + + + /** + * 解决metrics端点不显示jvm信息的问题(zyf) + */ + @Bean + InitializingBean forcePrometheusPostProcessor(BeanPostProcessor meterRegistryPostProcessor) { + return () -> meterRegistryPostProcessor.postProcessAfterInitialization(prometheusMeterRegistry, ""); + } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/WebSocketConfig.java b/digital-common/digital-config/src/main/java/digital/config/WebSocketConfig.java new file mode 100644 index 0000000..8137dfe --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/WebSocketConfig.java @@ -0,0 +1,22 @@ +package digital.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * @Description: WebSocketConfig + * @author: smcp + */ +@Configuration +public class WebSocketConfig { + /** + * 注入ServerEndpointExporter, + * 这个bean会自动注册使用了@ServerEndpoint注解声明的Websocket endpoint + */ + @Bean + public ServerEndpointExporter serverEndpointExporter() { + return new ServerEndpointExporter(); + } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/filter/FilterConfig.java b/digital-common/digital-config/src/main/java/digital/config/filter/FilterConfig.java new file mode 100644 index 0000000..c3f57f5 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/filter/FilterConfig.java @@ -0,0 +1,25 @@ +package digital.config.filter; + +import org.springframework.context.annotation.Configuration; + +/** + * author: smcp + * date:2022-08-08 16:31 + * description: + **/ + +@Configuration +public class FilterConfig { +// @Resource +// private MyAesFilter myAesFilter; +// +// @Bean +// public FilterRegistrationBean testFilterRegistration() { +// FilterRegistrationBean registration = new FilterRegistrationBean(myAesFilter); +// registration.addUrlPatterns("/*"); +// registration.setName("myAesFilter"); +// registration.setOrder(1); +// return registration; +// } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/filter/MyAesFilter.java b/digital-common/digital-config/src/main/java/digital/config/filter/MyAesFilter.java new file mode 100644 index 0000000..499fbf5 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/filter/MyAesFilter.java @@ -0,0 +1,116 @@ +package digital.config.filter; + + +import lombok.extern.slf4j.Slf4j; +import digital.util.encryption.AesEncryptUtil; + +import javax.servlet.FilterConfig; +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +/** + * author: smcp + * date:2022-08-08 16:23 + * description: + **/ +//@Component +@Slf4j +public class MyAesFilter implements Filter { +// @Value("${admin.encrypt.excludeUrl}") + private String ignoreStr; + private String[] ignoreArr; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + } + + /** + * 有错误相应返回-44 + * + * @param response + * @throws IOException + */ + private void getFailResponse(HttpServletResponse response) throws IOException { + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/json; charset=utf-8"); + PrintWriter out = null; + out = response.getWriter(); +// out.write("{\n" + +// " \"status\":"+ Constant.ENCRYPT_FAIL +",\n" + +// " \"message\": null,\n" + +// " \"data\": []\n" + +// "}"); + //加密后的错误消息 + out.write("+D+JO8tuwkrNbxnTTLdqStifmQceT+LlYETnIG/JZKrbAn+gIiqIp3VbzBV1y6R8B7aY53VM2xHa7cY3Osbnqw=="); + out.flush(); + out.close(); + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { +// if (ignoreArr != null) { +// ignoreArr = ignoreStr.split(","); +// } +// HttpServletRequest HttpRequest = (HttpServletRequest) request; +// HttpServletResponse HttpResponse = (HttpServletResponse) response; +// boolean flag = isIgnore(HttpRequest, ignoreArr); +// if (flag) { +// try { +// chain.doFilter(HttpRequest, HttpResponse); +// } catch (IOException e) { +// e.printStackTrace(); +// } catch (ServletException e) { +// e.printStackTrace(); +// } +// } else { + try { + //响应处理 包装响应对象 res 并缓存响应数据 + ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse) response); + //执行业务逻辑 交给下一个过滤器或servlet处理 + chain.doFilter(request, responseWrapper); + byte[] resData = responseWrapper.getResponseData(); + //设置响应内容格式,防止解析响应内容时出错 +// responseWrapper.setContentType("text/plain;charset=UTF-8"); + //加密响应报文并响应 + String encryptBASE64 = AesEncryptUtil.encrypt(new String(resData)); + PrintWriter out = response.getWriter(); + out.print(encryptBASE64); + out.flush(); + out.close(); + } catch (Exception e) { + try { + getFailResponse((HttpServletResponse) response); + } catch (IOException ioException) { + ioException.printStackTrace(); + } + e.printStackTrace(); + } +// } + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + } + + /** + * 哪些路径不处理 + * + * @param request + * @param strArr + * @return + */ + public boolean isIgnore(HttpServletRequest request, String[] strArr) { + String path = request.getRequestURI(); + for (String ignore : strArr) { + if (path.contains(ignore)) { + return true; + } + } + return false; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/filter/RequestWrapper.java b/digital-common/digital-config/src/main/java/digital/config/filter/RequestWrapper.java new file mode 100644 index 0000000..78dd321 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/filter/RequestWrapper.java @@ -0,0 +1,145 @@ +package digital.config.filter; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; +import java.nio.charset.Charset; +import java.util.*; + +/** + * author: smcp + * date:2022-08-08 17:48 + * description: + **/ +public class RequestWrapper extends HttpServletRequestWrapper { + private String requestBody = null; + //请求体 + private HttpServletRequest req = null; + // private final byte[] body;//保存流的字节数组 + private final Map reqHeaders=new HashMap<>(); + public RequestWrapper(HttpServletRequest request) throws IOException { + super(request); + this.req = request; +// this.reqHeaders = new HashMap(); +// String sessionStream = getRequestBodyStr(request);//读取流中的参数 +// body = sessionStream.getBytes(Charset.forName("UTF-8")); + } + public RequestWrapper(HttpServletRequest request, String requestBody) { + super(request); + this.requestBody = requestBody; + this.req = request; +// this.reqHeaders = request.get; + } + /** + * @Description: 获取请求body + * @Date: 2020/5/26 10:31 + * @Param: [request] + * @Return: java.lang.String + */ + public String getRequestBodyStr(final ServletRequest request) throws IOException { + StringBuilder sb = new StringBuilder(); + InputStream inputStream = null; + BufferedReader reader = null; + try { + inputStream = cloneInputStream(request.getInputStream()); + reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); + String line = ""; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + if (inputStream != null) { + inputStream.close(); + } + if (reader != null) { + reader.close(); + } + } + return sb.toString(); + } + /** + * @Description: 复制输入流 + * @Param: [inputStream] + * @Return: java.io.InputStream + */ + public InputStream cloneInputStream(ServletInputStream inputStream) throws IOException { + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + while ((len = inputStream.read(buffer)) > -1) { + byteArrayOutputStream.write(buffer, 0, len); + } + byteArrayOutputStream.flush(); + InputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + return byteArrayInputStream; + } + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + @Override + public ServletInputStream getInputStream() throws IOException { + final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody.getBytes(req.getCharacterEncoding())); + return new ServletInputStream() { + @Override + public boolean isFinished() { + return false; + } + @Override + public boolean isReady() { + return false; + } + @Override + public void setReadListener(ReadListener readListener) { + } + @Override + public int read() throws IOException { + return bais.read(); + } + }; + } + /** + * 添加header的名称和值 + * + * @param name + * @param value + */ + public void addHeader(String name, String value) { + reqHeaders.put(name, value); + } + @Override + public String getHeader(String name) { +// log.info("getHeader --->{}", name); + String headerValue = super.getHeader(name); + if (reqHeaders.containsKey(name)) { + headerValue = reqHeaders.get(name); + } + return headerValue; + } + /** + * 得到headers的名称 + */ + @Override + public Enumeration getHeaderNames() { + List names = Collections.list(super.getHeaderNames()); + for (String name : reqHeaders.keySet()) { + names.add(name); + } + return Collections.enumeration(names); + } + @Override + public Enumeration getHeaders(String name) { +// log.info("getHeaders name --->>>>>>{}", name); + List values = Collections.list(super.getHeaders(name)); +// log.info("getHeaders value --->>>>>>{}", values); + if (reqHeaders.containsKey(name)) { + values = Arrays.asList(reqHeaders.get(name)); + } + return Collections.enumeration(values); + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/filter/ResponseWrapper.java b/digital-common/digital-config/src/main/java/digital/config/filter/ResponseWrapper.java new file mode 100644 index 0000000..31ee580 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/filter/ResponseWrapper.java @@ -0,0 +1,76 @@ +package digital.config.filter; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.*; + +/** + * author: smcp + * date:2022-08-08 17:49 + * description: + **/ +public class ResponseWrapper extends HttpServletResponseWrapper { + private ByteArrayOutputStream buffer = null; + private ServletOutputStream out = null; + private PrintWriter writer = null; + public ResponseWrapper(HttpServletResponse response) throws IOException { + super(response); + buffer = new ByteArrayOutputStream();// 真正存储数据的流 + out = new WapperedOutputStream(buffer); + writer = new PrintWriter(new OutputStreamWriter(buffer,this.getCharacterEncoding())); + } + /** 重载父类获取outputstream的方法 */ + @Override + public ServletOutputStream getOutputStream() throws IOException { + return out; + } + /** 重载父类获取writer的方法 */ + @Override + public PrintWriter getWriter() throws UnsupportedEncodingException { + return writer; + } + /** 重载父类获取flushBuffer的方法 */ + @Override + public void flushBuffer() throws IOException { + if (out != null) { + out.flush(); + } + if (writer != null) { + writer.flush(); + } + } + @Override + public void reset() { + buffer.reset(); + } + /** 将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 */ + public byte[] getResponseData() throws IOException { + flushBuffer(); + return buffer.toByteArray(); + } + /** 内部类,对ServletOutputStream进行包装 */ + private class WapperedOutputStream extends ServletOutputStream { + private ByteArrayOutputStream bos = null; + public WapperedOutputStream(ByteArrayOutputStream stream) + throws IOException { + bos = stream; + } + @Override + public void write(int b) throws IOException { + bos.write(b); + } + @Override + public void write(byte[] b) throws IOException { + bos.write(b, 0, b.length); + } + @Override + public boolean isReady() { + return false; + } + @Override + public void setWriteListener(WriteListener writeListener) { + } + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/mns/MnsConfiguration.java b/digital-common/digital-config/src/main/java/digital/config/mns/MnsConfiguration.java new file mode 100644 index 0000000..e397008 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mns/MnsConfiguration.java @@ -0,0 +1,42 @@ +//package digital.config.mns; +// +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.boot.context.properties.ConfigurationProperties; +//import org.springframework.context.annotation.Configuration; +// +//@Configuration +//@ConfigurationProperties(prefix = "mns") +//public class MnsConfiguration { +// +// @Value("${mns.accountEndpoint}") +// private String accountEndpoint; +// @Value("${mns.accessKeyId}") +// private String accessKeyId; +// +// @Value("${mns.accessKeySecret}") +// private String accessKeySecret; +// +// public String getAccountEndpoint() { +// return accountEndpoint; +// } +// +// public void setAccountEndpoint(String accountEndpoint) { +// this.accountEndpoint = accountEndpoint; +// } +// +// public String getAccessKeyId() { +// return accessKeyId; +// } +// +// public void setAccessKeyId(String accessKeyId) { +// this.accessKeyId = accessKeyId; +// } +// +// public String getAccessKeySecret() { +// return accessKeySecret; +// } +// +// public void setAccessKeySecret(String accessKeySecret) { +// this.accessKeySecret = accessKeySecret; +// } +//} diff --git a/digital-common/digital-config/src/main/java/digital/config/mqtoken/TransmitUserTokenFilter.java b/digital-common/digital-config/src/main/java/digital/config/mqtoken/TransmitUserTokenFilter.java new file mode 100644 index 0000000..eddc04c --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mqtoken/TransmitUserTokenFilter.java @@ -0,0 +1,45 @@ +//package digital.config.mqtoken; +// +//import javax.servlet.*; +//import javax.servlet.http.HttpServletRequest; +//import java.io.IOException; +// +///** +// * 存放临时令牌Token到线程上下文 +// * +// * 供队列、定时任务 feign调用使用(解决无会话Token问题) +// * @author zyf +// */ +//public class TransmitUserTokenFilter implements Filter { +// +// private static String X_ACCESS_TOKEN="X-Access-Token"; +// +// public TransmitUserTokenFilter() { +// } +// +// @Override +// public void init(FilterConfig filterConfig) throws ServletException { +// } +// +// @Override +// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { +// this.initUserInfo((HttpServletRequest) request); +// chain.doFilter(request, response); +// } +// +// private void initUserInfo(HttpServletRequest request) { +// String token = request.getHeader(X_ACCESS_TOKEN); +// if (token!=null) { +// try { +// //将Token放入当前线程上下文中 +// UserTokenContext.setToken(token); +// } catch (Exception e) { +// //e.printStackTrace(); +// } +// } +// } +// +// @Override +// public void destroy() { +// } +//} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/mqtoken/UserTokenContext.java b/digital-common/digital-config/src/main/java/digital/config/mqtoken/UserTokenContext.java new file mode 100644 index 0000000..2b0dfcf --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mqtoken/UserTokenContext.java @@ -0,0 +1,31 @@ +package digital.config.mqtoken; + + +/** + * 用户Token线程上下文 + * + * 供队列、定时任务 feign调用使用(解决无会话Token问题) + * @author zyf + */ +public class UserTokenContext { + + /** + * 当前线程的TOKEN副本 + */ + private static ThreadLocal userToken = new ThreadLocal(); + + public UserTokenContext() { + } + + public static String getToken(){ + return userToken.get(); + } + + public static void setToken(String token){ + userToken.set(token); + } + + public static void remove() { + userToken.remove(); + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/mybatis/JeecgTenantParser.java b/digital-common/digital-config/src/main/java/digital/config/mybatis/JeecgTenantParser.java new file mode 100644 index 0000000..2d05bf8 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mybatis/JeecgTenantParser.java @@ -0,0 +1,129 @@ +//package digital.config.mybatis; +// +//import net.sf.jsqlparser.expression.BinaryExpression; +//import net.sf.jsqlparser.expression.Expression; +//import net.sf.jsqlparser.expression.Parenthesis; +//import net.sf.jsqlparser.expression.operators.conditional.AndExpression; +//import net.sf.jsqlparser.expression.operators.conditional.OrExpression; +//import net.sf.jsqlparser.expression.operators.relational.*; +//import net.sf.jsqlparser.schema.Column; +//import net.sf.jsqlparser.schema.Table; +//import net.sf.jsqlparser.statement.select.*; +// +//import java.util.List; +// +///** +// * 复写租户条件 +// */ +//public class JeecgTenantParser extends TenantSqlParser { +// +// /** +// * @param expression +// * @param table +// * @return +// */ +// protected Expression processTableAlias(Expression expression, Table table) { +// String tableAliasName; +// if (table.getAlias() == null) { +// tableAliasName = table.getName(); +// } else { +// tableAliasName = table.getAlias().getName(); +// } +// +// // in +// if (expression instanceof InExpression) { +// InExpression in = (InExpression) expression; +// if (in.getLeftExpression() instanceof Column) { +// setTableAliasNameForColumn((Column) in.getLeftExpression(), tableAliasName); +// } +// +// // 比较操作 +// } else if (expression instanceof BinaryExpression) { +// BinaryExpression compare = (BinaryExpression) expression; +// if (compare.getLeftExpression() instanceof Column) { +// setTableAliasNameForColumn((Column) compare.getLeftExpression(), tableAliasName); +// } else if (compare.getRightExpression() instanceof Column) { +// setTableAliasNameForColumn((Column) compare.getRightExpression(), tableAliasName); +// } +// +// // between +// } else if (expression instanceof Between) { +// Between between = (Between) expression; +// if (between.getLeftExpression() instanceof Column) { +// setTableAliasNameForColumn((Column) between.getLeftExpression(), tableAliasName); +// } +// } +// return expression; +// } +// +// private void setTableAliasNameForColumn(Column column, String tableAliasName) { +// column.setColumnName(tableAliasName + "." + column.getColumnName()); +// } +// +// /** +// * 默认是按 tenant_id=1 按等于条件追加 +// * +// * @param currentExpression 现有的条件:比如你原来的sql查询条件 +// * @param table +// * @return +// */ +// @Override +// protected Expression builderExpression(Expression currentExpression, Table table) { +// final Expression tenantExpression = this.getTenantHandler().getTenantId(true); +// Expression appendExpression; +// if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) { +// appendExpression = new EqualsTo(); +// ((EqualsTo) appendExpression).setLeftExpression(this.getAliasColumn(table)); +// ((EqualsTo) appendExpression).setRightExpression(tenantExpression); +// } else { +// appendExpression = processTableAlias(tenantExpression, table); +// } +// if (currentExpression == null) { +// return appendExpression; +// } +// if (currentExpression instanceof BinaryExpression) { +// BinaryExpression binaryExpression = (BinaryExpression) currentExpression; +// if (binaryExpression.getLeftExpression() instanceof FromItem) { +// processFromItem((FromItem) binaryExpression.getLeftExpression()); +// } +// if (binaryExpression.getRightExpression() instanceof FromItem) { +// processFromItem((FromItem) binaryExpression.getRightExpression()); +// } +// } else if (currentExpression instanceof InExpression) { +// InExpression inExp = (InExpression) currentExpression; +// ItemsList rightItems = inExp.getRightItemsList(); +// if (rightItems instanceof SubSelect) { +// processSelectBody(((SubSelect) rightItems).getSelectBody()); +// } +// } +// if (currentExpression instanceof OrExpression) { +// return new AndExpression(new Parenthesis(currentExpression), appendExpression); +// } else { +// return new AndExpression(currentExpression, appendExpression); +// } +// } +// +// @Override +// protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) { +// FromItem fromItem = plainSelect.getFromItem(); +// if (fromItem instanceof Table) { +// Table fromTable = (Table) fromItem; +// if (!this.getTenantHandler().doTableFilter(fromTable.getName())) { +// plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable)); +// if (addColumn) { +// plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn()))); +// } +// } +// } else { +// processFromItem(fromItem); +// } +// List joins = plainSelect.getJoins(); +// if (joins != null && joins.size() > 0) { +// joins.forEach(j -> { +// processJoin(j); +// processFromItem(j.getRightItem()); +// }); +// } +// } +// +//} diff --git a/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisInterceptor.java b/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisInterceptor.java new file mode 100644 index 0000000..e267d89 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisInterceptor.java @@ -0,0 +1,182 @@ +package digital.config.mybatis; + +import digital.base.vo.LoginUser; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.ibatis.binding.MapperMethod.ParamMap; +import org.apache.ibatis.executor.Executor; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.mapping.SqlCommandType; +import org.apache.ibatis.plugin.*; +import org.apache.shiro.SecurityUtils; +import org.springframework.stereotype.Component; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Field; +import java.util.Date; +import java.util.Properties; + +/** + * mybatis拦截器,自动注入创建人、创建时间、修改人、修改时间 + * @Author scott + * @Date 2019-01-19 + * + */ +@Slf4j +@Component +@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) }) +public class MybatisInterceptor implements Interceptor { + + @Override + public Object intercept(Invocation invocation) throws Throwable { + MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; + String sqlId = mappedStatement.getId(); + log.debug("------sqlId------" + sqlId); + SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType(); + Object parameter = invocation.getArgs()[1]; + log.debug("------sqlCommandType------" + sqlCommandType); + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + if (parameter == null) { + return invocation.proceed(); + } + if (SqlCommandType.INSERT == sqlCommandType) { + LoginUser sysUser = this.getLoginUser(); + Field[] fields = oConvertUtils.getAllFields(parameter); + for (Field field : fields) { + log.debug("------field.name------" + field.getName()); + try { + if ("createBy".equals(field.getName())) { + field.setAccessible(true); + Object localCreateBy = field.get(parameter); + field.setAccessible(false); + if (localCreateBy == null || "".equals(localCreateBy)) { + if (sysUser != null) { + // 登录人账号 + field.setAccessible(true); + field.set(parameter, sysUser.getUsername()); + field.setAccessible(false); + } + } + } + // 注入创建时间 + if ("createTime".equals(field.getName())) { + field.setAccessible(true); + Object localCreateDate = field.get(parameter); + field.setAccessible(false); + if (localCreateDate == null || "".equals(localCreateDate)) { + field.setAccessible(true); + field.set(parameter, new Date()); + field.setAccessible(false); + } + } + //注入部门编码 + if ("sysOrgCode".equals(field.getName())) { + field.setAccessible(true); + Object localSysOrgCode = field.get(parameter); + field.setAccessible(false); + if (localSysOrgCode == null || "".equals(localSysOrgCode)) { + // 获取登录用户信息 + if (sysUser != null) { + field.setAccessible(true); +// field.set(parameter, sysUser.getOrgCode()); + field.setAccessible(false); + } + } + } + // 注入appKet + if ("appKey".equals(field.getName())) { + field.setAccessible(true); + Object appKey = field.get(parameter); + field.setAccessible(false); + if (appKey == null || "".equals(appKey)) { + String headAppKey = request.getHeader("appKey"); + if (oConvertUtils.isNotEmpty(headAppKey)){ + field.setAccessible(true); + field.set(parameter, headAppKey); + field.setAccessible(false); + } + } + } + } catch (Exception e) { + } + } + } + if (SqlCommandType.UPDATE == sqlCommandType) { + LoginUser sysUser = this.getLoginUser(); + Field[] fields = null; + if (parameter instanceof ParamMap) { + ParamMap p = (ParamMap) parameter; + //update-begin-author:scott date:20190729 for:批量更新报错issues/IZA3Q-- + String et = "et"; + if (p.containsKey(et)) { + parameter = p.get(et); + } else { + parameter = p.get("param1"); + } + //update-end-author:scott date:20190729 for:批量更新报错issues/IZA3Q- + + //update-begin-author:scott date:20190729 for:更新指定字段时报错 issues/#516- + if (parameter == null) { + return invocation.proceed(); + } + //update-end-author:scott date:20190729 for:更新指定字段时报错 issues/#516- + + fields = oConvertUtils.getAllFields(parameter); + } else { + fields = oConvertUtils.getAllFields(parameter); + } + + for (Field field : fields) { + log.debug("------field.name------" + field.getName()); + try { + if ("updateBy".equals(field.getName())) { + //获取登录用户信息 + if (sysUser != null) { + // 登录账号 + field.setAccessible(true); + field.set(parameter, sysUser.getUsername()); + field.setAccessible(false); + } + } + if ("updateTime".equals(field.getName())) { + field.setAccessible(true); + field.set(parameter, new Date()); + field.setAccessible(false); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return invocation.proceed(); + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + // TODO Auto-generated method stub + } + + //update-begin--Author:scott Date:20191213 for:关于使用Quzrtz 开启线程任务, #465 + /** + * 获取登录用户 + * @return + */ + private LoginUser getLoginUser() { + LoginUser sysUser = null; + try { + sysUser = SecurityUtils.getSubject().getPrincipal() != null ? (LoginUser) SecurityUtils.getSubject().getPrincipal() : null; + } catch (Exception e) { + //e.printStackTrace(); + sysUser = null; + } + return sysUser; + } + //update-end--Author:scott Date:20191213 for:关于使用Quzrtz 开启线程任务, #465 + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisPlusSaasConfig.java b/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisPlusSaasConfig.java new file mode 100644 index 0000000..ab057b1 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mybatis/MybatisPlusSaasConfig.java @@ -0,0 +1,112 @@ +package digital.config.mybatis; + +import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; +import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler; +import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; +import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; +import digital.base.constant.CommonConstant; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; +import net.sf.jsqlparser.expression.Expression; +import net.sf.jsqlparser.expression.StringValue; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * 单数据源配置(jeecg.datasource.open = false时生效) + * + * @Author zhoujf + */ +@Configuration +//@MapperScan(value = {"org.jeecg.modules.**.mapper*", "smcp.**.mapper*"}) +@MapperScan(value = {"digital.**.mapper*"}) +public class MybatisPlusSaasConfig { + /** + * tenant_id 字段名 + */ + private static final String TENANT_FIELD_NAME = "app_key"; + /** + * 哪些表需要做多租户 表需要添加一个字段 tenant_id + */ + private static final List TENANT_TABLE = new ArrayList(); + + static { +// TENANT_TABLE.add("audio_manage"); +// TENANT_TABLE.add("background_manage"); +// TENANT_TABLE.add("digital_manage"); +// TENANT_TABLE.add("sys_file"); +// TENANT_TABLE.add("digital_manage"); +// TENANT_TABLE.add("video_manage"); +// //角色、菜单、部门 +// tenantTable.add("sys_role"); +// tenantTable.add("sys_permission"); +// tenantTable.add("sys_depart"); + } + + @Bean + public MybatisPlusInterceptor mybatisPlusInterceptor() { + MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); + // 先 add TenantLineInnerInterceptor 再 add PaginationInnerInterceptor + interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() { + @Override + public Expression getTenantId() { + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + if (Objects.isNull(request)) { + return new StringValue(""); + } + String tenantId = oConvertUtils.getString(request.getHeader("appKey"), "0"); + return new StringValue(tenantId); + } + + @Override + public String getTenantIdColumn() { + return TENANT_FIELD_NAME; + } + + // 返回 true 表示不走租户逻辑 + @Override + public boolean ignoreTable(String tableName) { + HttpServletRequest req = SpringContextUtils.getHttpServletRequest(); +// String tenantId = req.getHeader(CommonConstant.TENANT_ID); + String tenantId = oConvertUtils.getString(TenantContext.getTenant(), "0"); + //判断是否是超管 + if (CommonConstant.ADMIN_TENANT_ID.equals(tenantId)) { + return true; + } + for (String temp : TENANT_TABLE) { + if (temp.equalsIgnoreCase(tableName)) { + return false; + } + } + return true; + } + })); + interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); + interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); + return interceptor; + } + +// /** +// * 下个版本会删除,现在为了避免缓存出现问题不得不配置 +// * @return +// */ +// @Bean +// public ConfigurationCustomizer configurationCustomizer() { +// return configuration -> configuration.setUseDeprecatedExecutor(false); +// } +// /** +// * mybatis-plus SQL执行效率插件【生产环境可以关闭】 +// */ +// @Bean +// public PerformanceInterceptor performanceInterceptor() { +// return new PerformanceInterceptor(); +// } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/mybatis/TenantContext.java b/digital-common/digital-config/src/main/java/digital/config/mybatis/TenantContext.java new file mode 100644 index 0000000..ef82270 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/mybatis/TenantContext.java @@ -0,0 +1,25 @@ +package digital.config.mybatis; + +import lombok.extern.slf4j.Slf4j; + +/** + * 多租户 tenant_id存储器 + * @author: smcp + */ +@Slf4j +public class TenantContext { + private static ThreadLocal currentTenant = new ThreadLocal<>(); + + public static void setTenant(String tenant) { + log.debug(" setting tenant to " + tenant); + currentTenant.set(tenant); + } + + public static String getTenant() { + return currentTenant.get(); + } + + public static void clear(){ + currentTenant.remove(); + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/oss/MinioConfig.java b/digital-common/digital-config/src/main/java/digital/config/oss/MinioConfig.java new file mode 100644 index 0000000..c65a771 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/oss/MinioConfig.java @@ -0,0 +1,40 @@ +//package digital.config.oss; +// +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import digital.base.constant.CommonConstant; +//import digital.base.constant.SymbolConstant; +// +///** +// * Minio文件上传配置文件 +// * @author: smcp +// */ +//@Slf4j +//@Configuration +//public class MinioConfig { +// @Value(value = "${jeecg.minio.minio_url}") +// private String minioUrl; +// @Value(value = "${jeecg.minio.minio_name}") +// private String minioName; +// @Value(value = "${jeecg.minio.minio_pass}") +// private String minioPass; +// @Value(value = "${jeecg.minio.bucketName}") +// private String bucketName; +// +// @Bean +// public void initMinio() { +// if (!minioUrl.startsWith(CommonConstant.STR_HTTP)) { +// minioUrl = "http://" + minioUrl; +// } +// if (!minioUrl.endsWith(SymbolConstant.SINGLE_SLASH)) { +// minioUrl = minioUrl.concat(SymbolConstant.SINGLE_SLASH); +// } +//// MinioUtil.setMinioUrl(minioUrl); +//// MinioUtil.setMinioName(minioName); +//// MinioUtil.setMinioPass(minioPass); +//// MinioUtil.setBucketName(bucketName); +// } +// +//} diff --git a/digital-common/digital-config/src/main/java/digital/config/oss/OssConfiguration.java b/digital-common/digital-config/src/main/java/digital/config/oss/OssConfiguration.java new file mode 100644 index 0000000..99b2900 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/oss/OssConfiguration.java @@ -0,0 +1,39 @@ +package digital.config.oss; + +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import digital.util.oss.OssBootUtil; + +/** + * 云存储 配置 + * + * @author: smcp + */ +@Configuration +@Data +public class OssConfiguration { + @Value("${jeecg.oss.endpoint}") + private String endpoint; + @Value("${jeecg.oss.accessKey}") + private String accessKeyId; + @Value("${jeecg.oss.secretKey}") + private String accessKeySecret; + @Value("${jeecg.oss.bucketName}") + private String bucketName; + @Value("${jeecg.oss.staticDomain}") + private String staticDomain; +// @Value("${jeecg.oss.callBackUrl}") +// private String callBackUrl; + + @Bean + public void initOssBootConfiguration() { + OssBootUtil.setEndPoint(endpoint); + OssBootUtil.setAccessKeyId(accessKeyId); + OssBootUtil.setAccessKeySecret(accessKeySecret); + OssBootUtil.setBucketName(bucketName); + OssBootUtil.setStaticDomain(staticDomain); +// OssBootUtil.setCallBackUrl(callBackUrl); + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/shiro/JwtToken.java b/digital-common/digital-config/src/main/java/digital/config/shiro/JwtToken.java new file mode 100644 index 0000000..a935e48 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/shiro/JwtToken.java @@ -0,0 +1,28 @@ +package digital.config.shiro; + +import org.apache.shiro.authc.AuthenticationToken; + +/** + * @Author Scott + * @create 2018-07-12 15:19 + * @desc + **/ +public class JwtToken implements AuthenticationToken { + + private static final long serialVersionUID = 1L; + private String token; + + public JwtToken(String token) { + this.token = token; + } + + @Override + public Object getPrincipal() { + return token; + } + + @Override + public Object getCredentials() { + return token; + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/shiro/filters/CustomShiroFilterFactoryBean.java b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/CustomShiroFilterFactoryBean.java new file mode 100644 index 0000000..05145f2 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/CustomShiroFilterFactoryBean.java @@ -0,0 +1,77 @@ +package digital.config.shiro.filters; + +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.mgt.SecurityManager; +import org.apache.shiro.spring.web.ShiroFilterFactoryBean; +import org.apache.shiro.web.filter.InvalidRequestFilter; +import org.apache.shiro.web.filter.mgt.DefaultFilter; +import org.apache.shiro.web.filter.mgt.FilterChainManager; +import org.apache.shiro.web.filter.mgt.FilterChainResolver; +import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver; +import org.apache.shiro.web.mgt.WebSecurityManager; +import org.apache.shiro.web.servlet.AbstractShiroFilter; +import org.springframework.beans.factory.BeanInitializationException; + +import javax.servlet.Filter; +import java.util.Map; + +/** + * 自定义ShiroFilterFactoryBean解决资源中文路径问题 + * @author: smcp + */ +@Slf4j +public class CustomShiroFilterFactoryBean extends ShiroFilterFactoryBean { + @Override + public Class getObjectType() { + return MySpringShiroFilter.class; + } + + @Override + protected AbstractShiroFilter createInstance() throws Exception { + + SecurityManager securityManager = getSecurityManager(); + if (securityManager == null) { + String msg = "SecurityManager property must be set."; + throw new BeanInitializationException(msg); + } + + if (!(securityManager instanceof WebSecurityManager)) { + String msg = "The security manager does not implement the WebSecurityManager interface."; + throw new BeanInitializationException(msg); + } + + FilterChainManager manager = createFilterChainManager(); + //Expose the constructed FilterChainManager by first wrapping it in a + // FilterChainResolver implementation. The AbstractShiroFilter implementations + // do not know about FilterChainManagers - only resolvers: + PathMatchingFilterChainResolver chainResolver = new PathMatchingFilterChainResolver(); + chainResolver.setFilterChainManager(manager); + + Map filterMap = manager.getFilters(); + Filter invalidRequestFilter = filterMap.get(DefaultFilter.invalidRequest.name()); + if (invalidRequestFilter instanceof InvalidRequestFilter) { + //此处是关键,设置false跳过URL携带中文400,servletPath中文校验bug + ((InvalidRequestFilter) invalidRequestFilter).setBlockNonAscii(false); + } + //Now create a concrete ShiroFilter instance and apply the acquired SecurityManager and built + //FilterChainResolver. It doesn't matter that the instance is an anonymous inner class + //here - we're just using it because it is a concrete AbstractShiroFilter instance that accepts + //injection of the SecurityManager and FilterChainResolver: + return new MySpringShiroFilter((WebSecurityManager) securityManager, chainResolver); + } + + private static final class MySpringShiroFilter extends AbstractShiroFilter { + protected MySpringShiroFilter(WebSecurityManager webSecurityManager, FilterChainResolver resolver) { + if (webSecurityManager == null) { + throw new IllegalArgumentException("WebSecurityManager property cannot be null."); + } else { + this.setSecurityManager(webSecurityManager); + if (resolver != null) { + this.setFilterChainResolver(resolver); + } + + } + } + } + +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/shiro/filters/JwtFilter.java b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/JwtFilter.java new file mode 100644 index 0000000..d34f184 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/JwtFilter.java @@ -0,0 +1,110 @@ +package digital.config.shiro.filters; + +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMethod; +import digital.base.constant.CommonConstant; +import digital.config.mybatis.TenantContext; +import digital.config.shiro.JwtToken; +import digital.util.util.JwtUtil; +import digital.util.util.oConvertUtils; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Description: 鉴权登录拦截器 + * @Author: Scott + * @Date: 2018/10/7 + **/ +@Slf4j +public class JwtFilter extends BasicHttpAuthenticationFilter { + + /** + * 默认开启跨域设置(使用单体) + * 微服务情况下,此属性设置为false + */ + private boolean allowOrigin = true; + + public JwtFilter(){} + public JwtFilter(boolean allowOrigin){ + this.allowOrigin = allowOrigin; + } + + /** + * 执行登录认证 + * + * @param request + * @param response + * @param mappedValue + * @return + */ + @Override + protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { + try { + executeLogin(request, response); + return true; + } catch (Exception e) { + JwtUtil.responseError(response, 401, CommonConstant.TOKEN_IS_INVALID_MSG); + return false; + //throw new AuthenticationException("Token失效,请重新登录", e); + } + } + + /** + * + */ + @Override + protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + String token = httpServletRequest.getHeader(CommonConstant.X_ACCESS_TOKEN); + // update-begin--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数 + if (oConvertUtils.isEmpty(token)) { + token = httpServletRequest.getParameter("token"); + } + // update-end--Author:lvdandan Date:20210105 for:JT-355 OA聊天添加token验证,获取token参数 + + JwtToken jwtToken = new JwtToken(token); + // 提交给realm进行登入,如果错误他会抛出异常并被捕获 + getSubject(request, response).login(jwtToken); + // 如果没有抛出异常则代表登入成功,返回true + return true; + } + + /** + * 对跨域提供支持 + */ + @Override + protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + if(allowOrigin){ + httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, httpServletRequest.getHeader(HttpHeaders.ORIGIN)); + // 允许客户端请求方法 + httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,OPTIONS,PUT,DELETE"); + // 允许客户端提交的Header + String requestHeaders = httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS); + if (StringUtils.isNotEmpty(requestHeaders)) { + httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders); + } + // 允许客户端携带凭证信息(是否允许发送Cookie) + httpServletResponse.setHeader(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true"); + } + // 跨域时会首先发送一个option请求,这里我们给option请求直接返回正常状态 + if (RequestMethod.OPTIONS.name().equalsIgnoreCase(httpServletRequest.getMethod())) { + httpServletResponse.setStatus(HttpStatus.OK.value()); + return false; + } + //update-begin-author:taoyan date:20200708 for:多租户用到 + String tenantId = httpServletRequest.getHeader(CommonConstant.TENANT_ID); + TenantContext.setTenant(tenantId); + //update-end-author:taoyan date:20200708 for:多租户用到 + + return super.preHandle(request, response); + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/shiro/filters/ResourceCheckFilter.java b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/ResourceCheckFilter.java new file mode 100644 index 0000000..02cce80 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/shiro/filters/ResourceCheckFilter.java @@ -0,0 +1,68 @@ +package digital.config.shiro.filters; + +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.subject.Subject; +import org.apache.shiro.web.filter.AccessControlFilter; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Author Scott + * @create 2019-02-01 15:56 + * @desc 鉴权请求URL访问权限拦截器 + */ +@Slf4j +public class ResourceCheckFilter extends AccessControlFilter { + + private String errorUrl; + + public String getErrorUrl() { + return errorUrl; + } + + public void setErrorUrl(String errorUrl) { + this.errorUrl = errorUrl; + } + + /** + * 表示是否允许访问 ,如果允许访问返回true,否则false; + * + * @param servletRequest + * @param servletResponse + * @param o 表示写在拦截器中括号里面的字符串 mappedValue 就是 [urls] 配置中拦截器参数部分 + * @return + * @throws Exception + */ + @Override + protected boolean isAccessAllowed(ServletRequest servletRequest, ServletResponse servletResponse, Object o) throws Exception { + Subject subject = getSubject(servletRequest, servletResponse); + String url = getPathWithinApplication(servletRequest); + log.info("当前用户正在访问的 url => " + url); + return subject.isPermitted(url); + } + + /** + * onAccessDenied:表示当访问拒绝时是否已经处理了; 如果返回 true 表示需要继续处理; 如果返回 false + * 表示该拦截器实例已经处理了,将直接返回即可。 + * + * @param servletRequest + * @param servletResponse + * @return + * @throws Exception + */ + @Override + protected boolean onAccessDenied(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception { + log.info("当 isAccessAllowed 返回 false 的时候,才会执行 method onAccessDenied "); + + HttpServletRequest request = (HttpServletRequest) servletRequest; + HttpServletResponse response = (HttpServletResponse) servletResponse; + response.sendRedirect(request.getContextPath() + this.errorUrl); + + // 返回 false 表示已经处理,例如页面跳转啥的,表示不在走以下的拦截器了(如果还有配置的话) + return false; + } + +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthConfiguration.java b/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthConfiguration.java new file mode 100644 index 0000000..2f966c3 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthConfiguration.java @@ -0,0 +1,27 @@ +package digital.config.sign.interceptor; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * 签名 拦截器配置 + * @author: smcp + */ +@Configuration +public class SignAuthConfiguration implements WebMvcConfigurer { + public static String[] SIGN_URL_LIST = new String[]{"/sys/dict/getDictItems/*", "/sys/dict/loadDict/*", + "/sys/dict/loadDictOrderByValue/*", "/sys/dict/loadDictItem/*", "/sys/dict/loadTreeData", + "/sys/api/queryTableDictItemsByCode", "/sys/api/queryFilterTableDictInfo", "/sys/api/queryTableDictByKeys", + "/sys/api/translateDictFromTable", "/sys/api/translateDictFromTableByKeys"}; + @Bean + public SignAuthInterceptor signAuthInterceptor() { + return new SignAuthInterceptor(); + } + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(signAuthInterceptor()).addPathPatterns(SIGN_URL_LIST); + } +} diff --git a/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthInterceptor.java b/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthInterceptor.java new file mode 100644 index 0000000..58ec17d --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/sign/interceptor/SignAuthInterceptor.java @@ -0,0 +1,78 @@ +package digital.config.sign.interceptor; + + +import com.alibaba.fastjson.JSON; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.servlet.HandlerInterceptor; +import digital.base.constant.CommonConstant; +import digital.base.vo.Result; +import digital.config.sign.util.BodyReaderHttpServletRequestWrapper; +import digital.config.sign.util.HttpUtils; +import digital.config.sign.util.SignUtil; +import digital.util.util.DateUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.PrintWriter; +import java.util.SortedMap; + +/** + * 签名拦截器 + * @author qinfeng + */ +@Slf4j +public class SignAuthInterceptor implements HandlerInterceptor { + /** + * 5分钟有效期 + */ + private final static long MAX_EXPIRE = 5 * 60; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + log.info("request URI = " + request.getRequestURI()); + HttpServletRequest requestWrapper = new BodyReaderHttpServletRequestWrapper(request); + //获取全部参数(包括URL和body上的) + SortedMap allParams = HttpUtils.getAllParams(requestWrapper); + //对参数进行签名验证 + String headerSign = request.getHeader(CommonConstant.X_SIGN); + String xTimestamp = request.getHeader(CommonConstant.X_TIMESTAMP); + //客户端时间 + Long clientTimestamp = Long.parseLong(xTimestamp); + + int length = 14; + int length1000 = 1000; + //1.校验签名时间(兼容X_TIMESTAMP的新老格式) + if (xTimestamp.length() == length) { + //a. X_TIMESTAMP格式是 yyyyMMddHHmmss (例子:20220308152143) + if ((DateUtils.getCurrentTimestamp() - clientTimestamp) > MAX_EXPIRE) { + log.error("签名验证失败:X-TIMESTAMP已过期,注意系统时间和服务器时间是否有误差!"); + throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期"); + } + } else { + //b. X_TIMESTAMP格式是 时间戳 (例子:1646552406000) + if ((System.currentTimeMillis() - clientTimestamp) > (MAX_EXPIRE * length1000)) { + log.error("签名验证失败:X-TIMESTAMP已过期,注意系统时间和服务器时间是否有误差!"); + throw new IllegalArgumentException("签名验证失败:X-TIMESTAMP已过期"); + } + } + + //2.校验签名 + boolean isSigned = SignUtil.verifySign(allParams,headerSign); + + if (isSigned) { + log.debug("Sign 签名通过!Header Sign : {}",headerSign); + return true; + } else { + log.error("request URI = " + request.getRequestURI()); + log.error("Sign 签名校验失败!Header Sign : {}",headerSign); + //校验失败返回前端 + response.setCharacterEncoding("UTF-8"); + response.setContentType("application/json; charset=utf-8"); + PrintWriter out = response.getWriter(); + Result result = Result.error("Sign签名校验失败!"); + out.print(JSON.toJSON(result)); + return false; + } + } + +} diff --git a/digital-common/digital-config/src/main/java/digital/config/sign/util/BodyReaderHttpServletRequestWrapper.java b/digital-common/digital-config/src/main/java/digital/config/sign/util/BodyReaderHttpServletRequestWrapper.java new file mode 100644 index 0000000..1227a5f --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/sign/util/BodyReaderHttpServletRequestWrapper.java @@ -0,0 +1,107 @@ +package digital.config.sign.util; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; +import java.nio.charset.Charset; + +/** + * 保存过滤器里面的流 + * + * @author jeecg + * @date 20210621 + */ +public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper { + + private final byte[] body; + + public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) { + + super(request); + String sessionStream = getBodyString(request); + body = sessionStream.getBytes(Charset.forName("UTF-8")); + } + + /** + * 获取请求Body + * + * @param request + * @return + */ + public String getBodyString(final ServletRequest request) { + + StringBuilder sb = new StringBuilder(); + try (InputStream inputStream = cloneInputStream(request.getInputStream()); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")))) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + return sb.toString(); + } + + /** + * Description: 复制输入流
+ * + * @param inputStream + * @return
+ */ + public InputStream cloneInputStream(ServletInputStream inputStream) { + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); + byte[] buffer = new byte[1024]; + int len; + try { + while ((len = inputStream.read(buffer)) > -1) { + byteArrayOutputStream.write(buffer, 0, len); + } + byteArrayOutputStream.flush(); + } catch (IOException e) { + e.printStackTrace(); + } + return new ByteArrayInputStream(byteArrayOutputStream.toByteArray()); + } + + @Override + public BufferedReader getReader() { + + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + @Override + public ServletInputStream getInputStream() { + + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() { + + @Override + public int read() { + + return bais.read(); + } + + @Override + public boolean isFinished() { + + return false; + } + + @Override + public boolean isReady() { + + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + }; + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/sign/util/HttpUtils.java b/digital-common/digital-config/src/main/java/digital/config/sign/util/HttpUtils.java new file mode 100644 index 0000000..8bc9810 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/sign/util/HttpUtils.java @@ -0,0 +1,185 @@ +package digital.config.sign.util; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpMethod; +import digital.base.constant.SymbolConstant; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.HashMap; +import java.util.Map; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * http 工具类 获取请求中的参数 + * + * @author jeecg + * @date 20210621 + */ +@Slf4j +public class HttpUtils { + + /** + * 将URL的参数和body参数合并 + * + * @author jeecg + * @date 20210621 + * @param request + */ + public static SortedMap getAllParams(HttpServletRequest request) throws IOException { + + SortedMap result = new TreeMap<>(); + // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username + String pathVariable = request.getRequestURI().substring(request.getRequestURI().lastIndexOf("/") + 1); + if (pathVariable.contains(SymbolConstant.COMMA)) { + log.info(" pathVariable: {}",pathVariable); + String deString = URLDecoder.decode(pathVariable, "UTF-8"); + log.info(" pathVariable decode: {}",deString); + result.put(SignUtil.X_PATH_VARIABLE, deString); + } + // 获取URL上的参数 + Map urlParams = getUrlParams(request); + for (Map.Entry entry : urlParams.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + Map allRequestParam = new HashMap<>(16); + // get请求不需要拿body参数 + if (!HttpMethod.GET.name().equals(request.getMethod())) { + allRequestParam = getAllRequestParam(request); + } + // 将URL的参数和body参数进行合并 + if (allRequestParam != null) { + for (Map.Entry entry : allRequestParam.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + } + return result; + } + + /** + * 将URL的参数和body参数合并 + * + * @author jeecg + * @date 20210621 + * @param queryString + */ + public static SortedMap getAllParams(String url, String queryString, byte[] body, String method) + throws IOException { + + SortedMap result = new TreeMap<>(); + // 获取URL上最后带逗号的参数变量 sys/dict/getDictItems/sys_user,realname,username + String pathVariable = url.substring(url.lastIndexOf("/") + 1); + if (pathVariable.contains(SymbolConstant.COMMA)) { + log.info(" pathVariable: {}",pathVariable); + String deString = URLDecoder.decode(pathVariable, "UTF-8"); + log.info(" pathVariable decode: {}",deString); + result.put(SignUtil.X_PATH_VARIABLE, deString); + } + // 获取URL上的参数 + Map urlParams = getUrlParams(queryString); + for (Map.Entry entry : urlParams.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + Map allRequestParam = new HashMap<>(16); + // get请求不需要拿body参数 + if (!HttpMethod.GET.name().equals(method)) { + allRequestParam = getAllRequestParam(body); + } + // 将URL的参数和body参数进行合并 + if (allRequestParam != null) { + for (Map.Entry entry : allRequestParam.entrySet()) { + result.put((String)entry.getKey(), (String)entry.getValue()); + } + } + return result; + } + + /** + * 获取 Body 参数 + * + * @date 15:04 20210621 + * @param request + */ + public static Map getAllRequestParam(final HttpServletRequest request) throws IOException { + + BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); + String str = ""; + StringBuilder wholeStr = new StringBuilder(); + // 一行一行的读取body体里面的内容; + while ((str = reader.readLine()) != null) { + wholeStr.append(str); + } + // 转化成json对象 + return JSONObject.parseObject(wholeStr.toString(), Map.class); + } + + /** + * 获取 Body 参数 + * + * @date 15:04 20210621 + * @param body + */ + public static Map getAllRequestParam(final byte[] body) throws IOException { + if(body==null){ + return null; + } + String wholeStr = new String(body); + // 转化成json对象 + return JSONObject.parseObject(wholeStr.toString(), Map.class); + } + + /** + * 将URL请求参数转换成Map + * + * @param request + */ + public static Map getUrlParams(HttpServletRequest request) { + Map result = new HashMap<>(16); + if (oConvertUtils.isEmpty(request.getQueryString())) { + return result; + } + String param = ""; + try { + param = URLDecoder.decode(request.getQueryString(), "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + String[] params = param.split("&"); + for (String s : params) { + int index = s.indexOf("="); + result.put(s.substring(0, index), s.substring(index + 1)); + } + return result; + } + + /** + * 将URL请求参数转换成Map + * + * @param queryString + */ + public static Map getUrlParams(String queryString) { + Map result = new HashMap<>(16); + if (oConvertUtils.isEmpty(queryString)) { + return result; + } + String param = ""; + try { + param = URLDecoder.decode(queryString, "utf-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + String[] params = param.split("&"); + for (String s : params) { + int index = s.indexOf("="); + result.put(s.substring(0, index), s.substring(index + 1)); + } + return result; + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/sign/util/SignUtil.java b/digital-common/digital-config/src/main/java/digital/config/sign/util/SignUtil.java new file mode 100644 index 0000000..b4bbf8c --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/sign/util/SignUtil.java @@ -0,0 +1,59 @@ +package digital.config.sign.util; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.util.DigestUtils; +import org.springframework.util.StringUtils; +import digital.base.constant.SymbolConstant; +import digital.config.JeecgBaseConfig; +import digital.util.exception.JeecgBootException; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; + +import java.util.SortedMap; + +/** + * 签名工具类 + * + * @author jeecg + * @date 20210621 + */ +@Slf4j +public class SignUtil { + public static final String X_PATH_VARIABLE = "x-path-variable"; + + /** + * @param params + * 所有的请求参数都会在这里进行排序加密 + * @return 验证签名结果 + */ + public static boolean verifySign(SortedMap params,String headerSign) { + if (params == null || StringUtils.isEmpty(headerSign)) { + return false; + } + // 把参数加密 + String paramsSign = getParamsSign(params); + log.info("Param Sign : {}", paramsSign); + return !StringUtils.isEmpty(paramsSign) && headerSign.equals(paramsSign); + } + + /** + * @param params + * 所有的请求参数都会在这里进行排序加密 + * @return 得到签名 + */ + public static String getParamsSign(SortedMap params) { + //去掉 Url 里的时间戳 + params.remove("_t"); + String paramsJsonStr = JSONObject.toJSONString(params); + log.info("Param paramsJsonStr : {}", paramsJsonStr); + //设置签名秘钥 + JeecgBaseConfig jeecgBaseConfig = SpringContextUtils.getBean(JeecgBaseConfig.class); + String signatureSecret = jeecgBaseConfig.getSignatureSecret(); + String curlyBracket = SymbolConstant.DOLLAR + SymbolConstant.LEFT_CURLY_BRACKET; + if(oConvertUtils.isEmpty(signatureSecret) || signatureSecret.contains(curlyBracket)){ + throw new JeecgBootException("签名密钥 ${jeecg.signatureSecret} 缺少配置 !!"); + } + return DigestUtils.md5DigestAsHex((paramsJsonStr + signatureSecret).getBytes()).toUpperCase(); + } +} \ No newline at end of file diff --git a/digital-common/digital-config/src/main/java/digital/config/vo/Shiro.java b/digital-common/digital-config/src/main/java/digital/config/vo/Shiro.java new file mode 100644 index 0000000..da78817 --- /dev/null +++ b/digital-common/digital-config/src/main/java/digital/config/vo/Shiro.java @@ -0,0 +1,18 @@ +package digital.config.vo; + +/** + * @Description: TODO + * @author: scott + * @date: 2022年01月21日 14:23 + */ +public class Shiro { + private String excludeUrls = ""; + + public String getExcludeUrls() { + return excludeUrls; + } + + public void setExcludeUrls(String excludeUrls) { + this.excludeUrls = excludeUrls; + } +} diff --git a/digital-common/digital-util/pom.xml b/digital-common/digital-util/pom.xml new file mode 100644 index 0000000..fd37282 --- /dev/null +++ b/digital-common/digital-util/pom.xml @@ -0,0 +1,124 @@ + + + + digital-common + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-util + + + 8 + 8 + + + + + + + com.auth0 + java-jwt + ${java-jwt.version} + + + org.springframework + spring-aop + 5.3.18 + compile + + + + org.springframework.boot + spring-boot-starter-web + true + + + + org.springframework.boot + spring-boot-starter-data-redis + + + org.apache.commons + commons-pool2 + + + + cn.hutool + hutool-core + + + cn.hutool + hutool-crypto + + + + commons-beanutils + commons-beanutils + + + org.aspectj + aspectjweaver + + + com.baomidou + dynamic-datasource-spring-boot-starter + 3.2.0 + compile + + + com.baomidou + mybatis-plus-extension + 3.5.1 + compile + + + com.aliyun.oss + aliyun-sdk-oss + 3.11.2 + compile + + + io.minio + minio + + + + com.aliyun + aliyun-java-sdk-dysmsapi + ${aliyun-java-sdk-dysmsapi.version} + + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + + + org.apache.shiro + shiro-core + 1.9.1 + compile + + + org.jeecgframework.boot + digital-base + 3.2.0 + compile + + + org.jeecgframework + autopoi + 1.4.0 + compile + + + org.springframework.cloud + spring-cloud-commons + + + + \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveDecode.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveDecode.java new file mode 100644 index 0000000..55cc848 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveDecode.java @@ -0,0 +1,20 @@ +package digital.util.desensitization.annotation; + +import java.lang.annotation.*; + +/** + * 解密注解 + * + * 在方法上定义 将方法返回对象中的敏感字段 解密,需要注意的是,如果没有加密过,解密会出问题,返回原字符串 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SensitiveDecode { + + /** + * 指明需要脱敏的实体类class + * @return + */ + Class entity() default Object.class; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveEncode.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveEncode.java new file mode 100644 index 0000000..2e9f8ae --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveEncode.java @@ -0,0 +1,20 @@ +package digital.util.desensitization.annotation; + +import java.lang.annotation.*; + +/** + * 加密注解 + * + * 在方法上声明 将方法返回对象中的敏感字段 加密/格式化 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD}) +public @interface SensitiveEncode { + + /** + * 指明需要脱敏的实体类class + * @return + */ + Class entity() default Object.class; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveField.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveField.java new file mode 100644 index 0000000..8257d97 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/annotation/SensitiveField.java @@ -0,0 +1,22 @@ +package digital.util.desensitization.annotation; + + + +import digital.util.desensitization.enums.SensitiveEnum; + +import java.lang.annotation.*; + +/** + * 在字段上定义 标识字段存储的信息是敏感的 + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface SensitiveField { + + /** + * 不同类型处理不同 + * @return + */ + SensitiveEnum type() default SensitiveEnum.ENCODE; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/aspect/SensitiveDataAspect.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/aspect/SensitiveDataAspect.java new file mode 100644 index 0000000..1514474 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/aspect/SensitiveDataAspect.java @@ -0,0 +1,79 @@ +package digital.util.desensitization.aspect; + +import lombok.extern.slf4j.Slf4j; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Pointcut; +import org.aspectj.lang.reflect.MethodSignature; +import org.springframework.stereotype.Component; +import digital.util.desensitization.annotation.SensitiveDecode; +import digital.util.desensitization.annotation.SensitiveEncode; +import digital.util.desensitization.util.SensitiveInfoUtil; + +import java.lang.reflect.Method; +import java.util.List; + +/** + * 敏感数据切面处理类 + * @Author taoYan + * @Date 2022/4/20 17:45 + **/ +@Slf4j +@Aspect +@Component +public class SensitiveDataAspect { + /** + * 定义切点Pointcut + */ + @Pointcut("@annotation(digital.util.desensitization.annotation.SensitiveEncode) || @annotation(digital.util.desensitization.annotation.SensitiveDecode)") + public void sensitivePointCut() { + } + @Around("sensitivePointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + // 处理结果 + Object result = point.proceed(); + if(result == null){ + return result; + } + Class resultClass = result.getClass(); + log.debug(" resultClass = {}" , resultClass); + + if(resultClass.isPrimitive()){ + //是基本类型 直接返回 不需要处理 + return result; + } + // 获取方法注解信息:是哪个实体、是加密还是解密 + boolean isEncode = true; + Class entity = null; + MethodSignature methodSignature = (MethodSignature) point.getSignature(); + Method method = methodSignature.getMethod(); + SensitiveEncode encode = method.getAnnotation(SensitiveEncode.class); + if(encode==null){ + SensitiveDecode decode = method.getAnnotation(SensitiveDecode.class); + if(decode!=null){ + entity = decode.entity(); + isEncode = false; + } + }else{ + entity = encode.entity(); + } + + long startTime=System.currentTimeMillis(); + if(resultClass.equals(entity) || entity.equals(Object.class)){ + // 方法返回实体和注解的entity一样,如果注解没有申明entity属性则认为是(方法返回实体和注解的entity一样) + SensitiveInfoUtil.handlerObject(result, isEncode); + } else if(result instanceof List){ + // 方法返回List<实体> + SensitiveInfoUtil.handleList(result, entity, isEncode); + }else{ + // 方法返回一个对象 + SensitiveInfoUtil.handleNestedObject(result, entity, isEncode); + } + long endTime=System.currentTimeMillis(); + log.info((isEncode ? "加密操作," : "解密操作,") + "Aspect程序耗时:" + (endTime - startTime) + "ms"); + + return result; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/ResultTypeEnum.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/ResultTypeEnum.java new file mode 100644 index 0000000..0cb06ec --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/ResultTypeEnum.java @@ -0,0 +1,52 @@ +package digital.util.desensitization.enums; + + + +public enum ResultTypeEnum { + picture_1("401", "未检测到合适人脸"), + picture_2("402", "mesh服务返回错误"), + picture_3("403", "参数传递错误"), + picture_4("404", "结果上传失败,网络错误"), + picture_5("405", "算法处理错误"), + ; + + ResultTypeEnum(String code, String content) { + this.code = code; + this.content = content; + } + + private String code; + private String content; + + + public static ResultTypeEnum codeIn(String code) { + if (code == null) { + return null; + } else { + for (ResultTypeEnum em : ResultTypeEnum.values()) { + if (em.getCode().equals(code)) { + return em; + } + } + return null; + } + } + + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/SensitiveEnum.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/SensitiveEnum.java new file mode 100644 index 0000000..32837bd --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/enums/SensitiveEnum.java @@ -0,0 +1,55 @@ +package digital.util.desensitization.enums; + +/** + * 敏感字段信息类型 + */ +public enum SensitiveEnum { + + + /** + * 加密 + */ + ENCODE, + + /** + * 中文名 + */ + CHINESE_NAME, + + /** + * 身份证号 + */ + ID_CARD, + + /** + * 座机号 + */ + FIXED_PHONE, + + /** + * 手机号 + */ + MOBILE_PHONE, + + /** + * 地址 + */ + ADDRESS, + + /** + * 电子邮件 + */ + EMAIL, + + /** + * 银行卡 + */ + BANK_CARD, + + /** + * 公司开户银行联号 + */ + CNAPS_CODE; + + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/desensitization/util/SensitiveInfoUtil.java b/digital-common/digital-util/src/main/java/digital/util/desensitization/util/SensitiveInfoUtil.java new file mode 100644 index 0000000..3a29de9 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/desensitization/util/SensitiveInfoUtil.java @@ -0,0 +1,362 @@ +package digital.util.desensitization.util; + +import lombok.extern.slf4j.Slf4j; +import digital.util.desensitization.annotation.SensitiveField; +import digital.util.desensitization.enums.SensitiveEnum; +import digital.util.encryption.AesEncryptUtil; +import digital.util.util.oConvertUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.ParameterizedType; +import java.util.Collections; +import java.util.List; + +/** + * 敏感信息处理工具类 + * @author taoYan + * @date 2022/4/20 18:01 + **/ +@Slf4j +public class SensitiveInfoUtil { + + /** + * 处理嵌套对象 + * @param obj 方法返回值 + * @param entity 实体class + * @param isEncode 是否加密(true: 加密操作 / false:解密操作) + * @throws IllegalAccessException + */ + public static void handleNestedObject(Object obj, Class entity, boolean isEncode) throws IllegalAccessException { + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + if(field.getType().isPrimitive()){ + continue; + } + if(field.getType().equals(entity)){ + // 对象里面是实体 + field.setAccessible(true); + Object nestedObject = field.get(obj); + handlerObject(nestedObject, isEncode); + break; + }else{ + // 对象里面是List<实体> + if(field.getGenericType() instanceof ParameterizedType){ + ParameterizedType pt = (ParameterizedType)field.getGenericType(); + if(pt.getRawType().equals(List.class)){ + if(pt.getActualTypeArguments()[0].equals(entity)){ + field.setAccessible(true); + Object nestedObject = field.get(obj); + handleList(nestedObject, entity, isEncode); + break; + } + } + } + } + } + } + + /** + * 处理Object + * @param obj 方法返回值 + * @param isEncode 是否加密(true: 加密操作 / false:解密操作) + * @return + * @throws IllegalAccessException + */ + public static Object handlerObject(Object obj, boolean isEncode) throws IllegalAccessException { + log.debug(" obj --> "+ obj.toString()); + long startTime=System.currentTimeMillis(); + if (oConvertUtils.isEmpty(obj)) { + return obj; + } + // 判断是不是一个对象 + Field[] fields = obj.getClass().getDeclaredFields(); + for (Field field : fields) { + boolean isSensitiveField = field.isAnnotationPresent(SensitiveField.class); + if(isSensitiveField){ + // 必须有SensitiveField注解 才作处理 + if(field.getType().isAssignableFrom(String.class)){ + //必须是字符串类型 才作处理 + field.setAccessible(true); + String realValue = (String) field.get(obj); + if(realValue==null || "".equals(realValue)){ + continue; + } + SensitiveField sf = field.getAnnotation(SensitiveField.class); + if(isEncode==true){ + //加密 + String value = SensitiveInfoUtil.getEncodeData(realValue, sf.type()); + field.set(obj, value); + }else{ + //解密只处理 encode类型的 + if(sf.type().equals(SensitiveEnum.ENCODE)){ + String value = SensitiveInfoUtil.getDecodeData(realValue); + field.set(obj, value); + } + } + } + } + } + //long endTime=System.currentTimeMillis(); + //log.info((isEncode ? "加密操作," : "解密操作,") + "当前程序耗时:" + (endTime - startTime) + "ms"); + return obj; + } + + /** + * 处理 List<实体> + * @param obj + * @param entity + * @param isEncode(true: 加密操作 / false:解密操作) + */ + public static void handleList(Object obj, Class entity, boolean isEncode){ + List list = (List)obj; + if(list.size()>0){ + Object first = list.get(0); + if(first.getClass().equals(entity)){ + for(int i=0; i + */ + private static String chineseName(String fullName) { + if (oConvertUtils.isEmpty(fullName)) { + return ""; + } + return formatRight(fullName, 1); + } + + /** + * [中文姓名] 只显示第一个汉字,其他隐藏为2个星号 + * @param familyName 姓 + * @param firstName 名 + * @return <例子:李**> + */ + private static String chineseName(String familyName, String firstName) { + if (oConvertUtils.isEmpty(familyName) || oConvertUtils.isEmpty(firstName)) { + return ""; + } + return chineseName(familyName + firstName); + } + + /** + * [身份证号] 显示最后四位,其他隐藏。共计18位或者15位。 + * @param id 身份证号 + * @return <例子:*************5762> + */ + private static String idCardNum(String id) { + if (oConvertUtils.isEmpty(id)) { + return ""; + } + return formatLeft(id, 4); + + } + + /** + * [固定电话] 后四位,其他隐藏 + * @param num 固定电话 + * @return <例子:****1234> + */ + private static String fixedPhone(String num) { + if (oConvertUtils.isEmpty(num)) { + return ""; + } + return formatLeft(num, 4); + } + + /** + * [手机号码] 前三位,后四位,其他隐藏 + * @param num 手机号码 + * @return <例子:138******1234> + */ + private static String mobilePhone(String num) { + if (oConvertUtils.isEmpty(num)) { + return ""; + } + int len = num.length(); + if(len<11){ + return num; + } + return formatBetween(num, 3, 4); + } + + /** + * [地址] 只显示到地区,不显示详细地址;我们要对个人信息增强保护 + * @param address 地址 + * @param sensitiveSize 敏感信息长度 + * @return <例子:北京市海淀区****> + */ + private static String address(String address, int sensitiveSize) { + if (oConvertUtils.isEmpty(address)) { + return ""; + } + int len = address.length(); + if(len + */ + private static String email(String email) { + if (oConvertUtils.isEmpty(email)) { + return ""; + } + int index = email.indexOf("@"); + if (index <= 1){ + return email; + } + String begin = email.substring(0, 1); + String end = email.substring(index); + String stars = "**"; + return begin + stars + end; + } + + /** + * [银行卡号] 前六位,后四位,其他用星号隐藏每位1个星号 + * @param cardNum 银行卡号 + * @return <例子:6222600**********1234> + */ + private static String bankCard(String cardNum) { + if (oConvertUtils.isEmpty(cardNum)) { + return ""; + } + return formatBetween(cardNum, 6, 4); + } + + /** + * [公司开户银行联号] 公司开户银行联行号,显示前两位,其他用星号隐藏,每位1个星号 + * @param code 公司开户银行联号 + * @return <例子:12********> + */ + private static String cnapsCode(String code) { + if (oConvertUtils.isEmpty(code)) { + return ""; + } + return formatRight(code, 2); + } + + + /** + * 将右边的格式化成* + * @param str 字符串 + * @param reservedLength 保留长度 + * @return 格式化后的字符串 + */ + private static String formatRight(String str, int reservedLength){ + String name = str.substring(0, reservedLength); + String stars = String.join("", Collections.nCopies(str.length()-reservedLength, "*")); + return name + stars; + } + + /** + * 将左边的格式化成* + * @param str 字符串 + * @param reservedLength 保留长度 + * @return 格式化后的字符串 + */ + private static String formatLeft(String str, int reservedLength){ + int len = str.length(); + String show = str.substring(len-reservedLength); + String stars = String.join("", Collections.nCopies(len-reservedLength, "*")); + return stars + show; + } + + /** + * 将中间的格式化成* + * @param str 字符串 + * @param beginLen 开始保留长度 + * @param endLen 结尾保留长度 + * @return 格式化后的字符串 + */ + private static String formatBetween(String str, int beginLen, int endLen){ + int len = str.length(); + String begin = str.substring(0, beginLen); + String end = str.substring(len-endLen); + String stars = String.join("", Collections.nCopies(len-beginLen-endLen, "*")); + return begin + stars + end; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/encryption/AesEncryptUtil.java b/digital-common/digital-util/src/main/java/digital/util/encryption/AesEncryptUtil.java new file mode 100644 index 0000000..9efe8e0 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/encryption/AesEncryptUtil.java @@ -0,0 +1,126 @@ +package digital.util.encryption; + +import org.apache.shiro.codec.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * @Description: AES 加密 + * @author: smcp + * @date: 2022/3/30 11:48 + */ +public class AesEncryptUtil { + + /** + * 使用AES-128-CBC加密模式 key和iv可以相同 + */ + private static String KEY = EncryptedString.key; + private static String IV = EncryptedString.iv; + + /** + * 加密方法 + * @param data 要加密的数据 + * @param key 加密key + * @param iv 加密iv + * @return 加密的结果 + * @throws Exception + */ + public static String encrypt(String data, String key, String iv) throws Exception { + try { + + //"算法/模式/补码方式"NoPadding PkcsPadding + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + int blockSize = cipher.getBlockSize(); + + byte[] dataBytes = data.getBytes(); + int plaintextLength = dataBytes.length; + if (plaintextLength % blockSize != 0) { + plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); + } + + byte[] plaintext = new byte[plaintextLength]; + System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); + + SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); + IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); + + cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); + byte[] encrypted = cipher.doFinal(plaintext); + + return Base64.encodeToString(encrypted); + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 解密方法 + * @param data 要解密的数据 + * @param key 解密key + * @param iv 解密iv + * @return 解密的结果 + * @throws Exception + */ + public static String desEncrypt(String data, String key, String iv) throws Exception { + try { + byte[] encrypted1 = Base64.decode(data); + + Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); + SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); + IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); + + cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); + + byte[] original = cipher.doFinal(encrypted1); + String originalString = new String(original); + return originalString; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 使用默认的key和iv加密 + * @param data + * @return + * @throws Exception + */ + public static String encrypt(String data) throws Exception { + return encrypt(data, KEY, IV); + } + + /** + * 使用默认的key和iv解密 + * @param data + * @return + * @throws Exception + */ + public static String desEncrypt(String data) throws Exception { + return desEncrypt(data, KEY, IV); + } + + + +// /** +// * 测试 +// */ +// public static void main(String args[]) throws Exception { +// String test1 = "sa"; +// String test =new String(test1.getBytes(),"UTF-8"); +// String data = null; +// String key = KEY; +// String iv = IV; +// // /g2wzfqvMOeazgtsUVbq1kmJawROa6mcRAzwG1/GeJ4= +// data = encrypt(test, key, iv); +// System.out.println("数据:"+test); +// System.out.println("加密:"+data); +// String jiemi =desEncrypt(data, key, iv).trim(); +// System.out.println("解密:"+jiemi); +// } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/encryption/EncryptedString.java b/digital-common/digital-util/src/main/java/digital/util/encryption/EncryptedString.java new file mode 100644 index 0000000..f942e7f --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/encryption/EncryptedString.java @@ -0,0 +1,22 @@ +package digital.util.encryption; + + +import lombok.Data; + +/** + * @Description: EncryptedString + * @author: smcp + */ +@Data +public class EncryptedString { + + /** + * 长度为16个字符 + */ + public static String key = "1234567890adbcde"; + + /** + * 长度为16个字符 + */ + public static String iv = "1234567890hjlkew"; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/es/JeecgElasticsearchTemplate.java b/digital-common/digital-util/src/main/java/digital/util/es/JeecgElasticsearchTemplate.java new file mode 100644 index 0000000..0d46089 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/es/JeecgElasticsearchTemplate.java @@ -0,0 +1,551 @@ +//package digital.util.util.es; +// +//import com.alibaba.fastjson.JSONArray; +//import com.alibaba.fastjson.JSONObject; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.http.HttpHeaders; +//import org.springframework.http.HttpMethod; +//import org.springframework.http.HttpStatus; +//import org.springframework.http.ResponseEntity; +//import org.springframework.stereotype.Component; +//import org.springframework.util.StringUtils; +//import digital.util.util.RestUtil; +//import digital.util.util.oConvertUtils; +// +//import java.util.*; +// +///** +// * 关于 ElasticSearch 的一些方法(创建索引、添加数据、查询等) +// * +// * @author sunjianlei +// */ +//@Slf4j +//@Component +//public class JeecgElasticsearchTemplate { +// /** +// * ElasticSearch 最大可返回条目数 +// */ +// public static final int ES_MAX_SIZE = 10000; +// private final String FORMAT_JSON = "format=json"; +// /** +// * es7 +// */ +// public static final String IE_SEVEN = "7"; +// /** +// * url not found 404 +// */ +// public static final String URL_NOT_FOUND = "404 Not Found"; +// /** +// * es服务地址 +// */ +// private String baseUrl; +// /** +// * Elasticsearch 的版本号 +// */ +// private String version = null; +// +// public JeecgElasticsearchTemplate(@Value("${jeecg.elasticsearch.cluster-nodes}") String baseUrl, @Value("${jeecg.elasticsearch.check-enabled}") boolean checkEnabled) { +// log.debug("JeecgElasticsearchTemplate BaseURL:" + baseUrl); +// if (oConvertUtils.isNotEmpty(baseUrl)) { +// this.baseUrl = baseUrl; +// // 验证配置的ES地址是否有效 +// if (checkEnabled) { +// try { +// this.getElasticsearchVersion(); +// log.info("ElasticSearch 服务连接成功"); +// log.info("ElasticSearch version: " + this.version); +// } catch (Exception e) { +// this.version = ""; +// log.warn("ElasticSearch 服务连接失败,原因:配置未通过。可能是BaseURL未配置或配置有误,也可能是Elasticsearch服务未启动。接下来将会拒绝执行任何方法!"); +// } +// } +// } +// } +// +// /** +// * 获取 Elasticsearch 的版本号信息,失败返回null +// */ +// private void getElasticsearchVersion() { +// if (this.version == null) { +// String url = this.getBaseUrl().toString(); +// JSONObject result = RestUtil.get(url); +// if (result != null) { +// JSONObject v = result.getJSONObject("version"); +// this.version = v.getString("number"); +// } +// } +// } +// +// public StringBuilder getBaseUrl(String indexName, String typeName) { +// typeName = typeName.trim().toLowerCase(); +// return this.getBaseUrl(indexName).append("/").append(typeName); +// } +// +// public StringBuilder getBaseUrl(String indexName) { +// indexName = indexName.trim().toLowerCase(); +// return this.getBaseUrl().append("/").append(indexName); +// } +// +// public StringBuilder getBaseUrl() { +// return new StringBuilder("http://").append(this.baseUrl); +// } +// +// /** +// * cat 查询ElasticSearch系统数据,返回json +// */ +// private ResponseEntity cat(String urlAfter, Class responseType) { +// String url = this.getBaseUrl().append("/_cat").append(urlAfter).append("?").append(FORMAT_JSON).toString(); +// return RestUtil.request(url, HttpMethod.GET, null, null, null, responseType); +// } +// +// /** +// * 查询所有索引 +// *

+// * 查询地址:GET http://{baseUrl}/_cat/indices +// */ +// public JSONArray getIndices() { +// return getIndices(null); +// } +// +// +// /** +// * 查询单个索引 +// *

+// * 查询地址:GET http://{baseUrl}/_cat/indices/{indexName} +// */ +// public JSONArray getIndices(String indexName) { +// StringBuilder urlAfter = new StringBuilder("/indices"); +// if (!StringUtils.isEmpty(indexName)) { +// urlAfter.append("/").append(indexName.trim().toLowerCase()); +// } +// return cat(urlAfter.toString(), JSONArray.class).getBody(); +// } +// +// /** +// * 索引是否存在 +// */ +// public boolean indexExists(String indexName) { +// try { +// JSONArray array = getIndices(indexName); +// return array != null; +// } catch (org.springframework.web.client.HttpClientErrorException ex) { +// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { +// return false; +// } else { +// throw ex; +// } +// } +// } +// +// /** +// * 根据ID获取索引数据,未查询到返回null +// *

+// * 查询地址:GET http://{baseUrl}/{indexName}/{typeName}/{dataId} +// * +// * @param indexName 索引名称 +// * @param typeName type,一个任意字符串,用于分类 +// * @param dataId 数据id +// * @return +// */ +// public JSONObject getDataById(String indexName, String typeName, String dataId) { +// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString(); +// log.info("url:" + url); +// JSONObject result = RestUtil.get(url); +// boolean found = result.getBoolean("found"); +// if (found) { +// return result.getJSONObject("_source"); +// } else { +// return null; +// } +// } +// +// /** +// * 创建索引 +// *

+// * 查询地址:PUT http://{baseUrl}/{indexName} +// */ +// public boolean createIndex(String indexName) { +// String url = this.getBaseUrl(indexName).toString(); +// +// /* 返回结果 (仅供参考) +// "createIndex": { +// "shards_acknowledged": true, +// "acknowledged": true, +// "index": "hello_world" +// } +// */ +// try { +// return RestUtil.put(url).getBoolean("acknowledged"); +// } catch (org.springframework.web.client.HttpClientErrorException ex) { +// if (HttpStatus.BAD_REQUEST == ex.getStatusCode()) { +// log.warn("索引创建失败:" + indexName + " 已存在,无需再创建"); +// } else { +// ex.printStackTrace(); +// } +// } +// return false; +// } +// +// /** +// * 删除索引 +// *

+// * 查询地址:DELETE http://{baseUrl}/{indexName} +// */ +// public boolean removeIndex(String indexName) { +// String url = this.getBaseUrl(indexName).toString(); +// try { +// return RestUtil.delete(url).getBoolean("acknowledged"); +// } catch (org.springframework.web.client.HttpClientErrorException ex) { +// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { +// log.warn("索引删除失败:" + indexName + " 不存在,无需删除"); +// } else { +// ex.printStackTrace(); +// } +// } +// return false; +// } +// +// /** +// * 获取索引字段映射(可获取字段类型) +// *

+// * +// * @param indexName 索引名称 +// * @param typeName 分类名称 +// * @return +// */ +// public JSONObject getIndexMapping(String indexName, String typeName) { +// String url = this.getBaseUrl(indexName, typeName).append("/_mapping?").append(FORMAT_JSON).toString(); +// // 针对 es 7.x 版本做兼容 +// this.getElasticsearchVersion(); +// if (oConvertUtils.isNotEmpty(this.version) && this.version.startsWith(IE_SEVEN)) { +// url += "&include_type_name=true"; +// } +// log.info("getIndexMapping-url:" + url); +// /* +// * 参考返回JSON结构: +// * +// *{ +// * // 索引名称 +// * "[indexName]": { +// * "mappings": { +// * // 分类名称 +// * "[typeName]": { +// * "properties": { +// * // 字段名 +// * "input_number": { +// * // 字段类型 +// * "type": "long" +// * }, +// * "input_string": { +// * "type": "text", +// * "fields": { +// * "keyword": { +// * "type": "keyword", +// * "ignore_above": 256 +// * } +// * } +// * } +// * } +// * } +// * } +// * } +// * } +// */ +// try { +// return RestUtil.get(url); +// } catch (org.springframework.web.client.HttpClientErrorException e) { +// String message = e.getMessage(); +// if (message != null && message.contains(URL_NOT_FOUND)) { +// return null; +// } +// throw e; +// } +// } +// +// /** +// * 获取索引字段映射,返回Java实体类 +// * +// * @param indexName +// * @param typeName +// * @return +// */ +// public Map getIndexMappingFormat(String indexName, String typeName, Class clazz) { +// JSONObject mapping = this.getIndexMapping(indexName, typeName); +// Map map = new HashMap<>(5); +// if (mapping == null) { +// return map; +// } +// // 获取字段属性 +// JSONObject properties = mapping.getJSONObject(indexName) +// .getJSONObject("mappings") +// .getJSONObject(typeName) +// .getJSONObject("properties"); +// // 封装成 java类型 +// for (String key : properties.keySet()) { +// T entity = properties.getJSONObject(key).toJavaObject(clazz); +// map.put(key, entity); +// } +// return map; +// } +// +// /** +// * 保存数据,详见:saveOrUpdate +// */ +// public boolean save(String indexName, String typeName, String dataId, JSONObject data) { +// return this.saveOrUpdate(indexName, typeName, dataId, data); +// } +// +// /** +// * 更新数据,详见:saveOrUpdate +// */ +// public boolean update(String indexName, String typeName, String dataId, JSONObject data) { +// return this.saveOrUpdate(indexName, typeName, dataId, data); +// } +// +// /** +// * 保存或修改索引数据 +// *

+// * 查询地址:PUT http://{baseUrl}/{indexName}/{typeName}/{dataId} +// * +// * @param indexName 索引名称 +// * @param typeName type,一个任意字符串,用于分类 +// * @param dataId 数据id +// * @param data 要存储的数据 +// * @return +// */ +// public boolean saveOrUpdate(String indexName, String typeName, String dataId, JSONObject data) { +// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).append("?refresh=wait_for").toString(); +// /* 返回结果(仅供参考) +// "createIndexA2": { +// "result": "created", +// "_shards": { +// "total": 2, +// "successful": 1, +// "failed": 0 +// }, +// "_seq_no": 0, +// "_index": "test_index_1", +// "_type": "test_type_1", +// "_id": "a2", +// "_version": 1, +// "_primary_term": 1 +// } +// */ +// +// try { +// // 去掉 data 中为空的值 +// Set keys = data.keySet(); +// List emptyKeys = new ArrayList<>(keys.size()); +// for (String key : keys) { +// String value = data.getString(key); +// //1、剔除空值 +// if (oConvertUtils.isEmpty(value) || "[]".equals(value)) { +// emptyKeys.add(key); +// } +// //2、剔除上传控件值(会导致ES同步失败,报异常failed to parse field [ge_pic] of type [text] ) +// if (oConvertUtils.isNotEmpty(value) && value.indexOf("[{") != -1) { +// emptyKeys.add(key); +// log.info("-------剔除上传控件字段------------key: " + key); +// } +// } +// for (String key : emptyKeys) { +// data.remove(key); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// try { +// String result = RestUtil.put(url, data).getString("result"); +// return "created".equals(result) || "updated".equals(result); +// } catch (Exception e) { +// log.error(e.getMessage() + "\n-- url: " + url + "\n-- data: " + data.toJSONString()); +// //TODO 打印接口返回异常json +// return false; +// } +// } +// +// /** +// * 批量保存数据 +// * +// * @param indexName 索引名称 +// * @param typeName type,一个任意字符串,用于分类 +// * @param dataList 要存储的数据数组,每行数据必须包含id +// * @return +// */ +// public boolean saveBatch(String indexName, String typeName, JSONArray dataList) { +// String url = this.getBaseUrl().append("/_bulk").append("?refresh=wait_for").toString(); +// StringBuilder bodySb = new StringBuilder(); +// for (int i = 0; i < dataList.size(); i++) { +// JSONObject data = dataList.getJSONObject(i); +// String id = data.getString("id"); +// // 该行的操作 +// // {"create": {"_id":"${id}", "_index": "${indexName}", "_type": "${typeName}"}} +// JSONObject action = new JSONObject(); +// JSONObject actionInfo = new JSONObject(); +// actionInfo.put("_id", id); +// actionInfo.put("_index", indexName); +// actionInfo.put("_type", typeName); +// action.put("create", actionInfo); +// bodySb.append(action.toJSONString()).append("\n"); +// // 该行的数据 +// data.remove("id"); +// bodySb.append(data.toJSONString()).append("\n"); +// } +// System.out.println("+-+-+-: bodySb.toString(): " + bodySb.toString()); +// HttpHeaders headers = RestUtil.getHeaderApplicationJson(); +// RestUtil.request(url, HttpMethod.PUT, headers, null, bodySb, JSONObject.class); +// return true; +// } +// +// /** +// * 删除索引数据 +// *

+// * 请求地址:DELETE http://{baseUrl}/{indexName}/{typeName}/{dataId} +// */ +// public boolean delete(String indexName, String typeName, String dataId) { +// String url = this.getBaseUrl(indexName, typeName).append("/").append(dataId).toString(); +// /* 返回结果(仅供参考) +// { +// "_index": "es_demo", +// "_type": "docs", +// "_id": "001", +// "_version": 3, +// "result": "deleted", +// "_shards": { +// "total": 1, +// "successful": 1, +// "failed": 0 +// }, +// "_seq_no": 28, +// "_primary_term": 18 +// } +// */ +// try { +// return "deleted".equals(RestUtil.delete(url).getString("result")); +// } catch (org.springframework.web.client.HttpClientErrorException ex) { +// if (HttpStatus.NOT_FOUND == ex.getStatusCode()) { +// return false; +// } else { +// throw ex; +// } +// } +// } +// +// +// /* = = = 以下关于查询和查询条件的方法 = = =*/ +// +// /** +// * 查询数据 +// *

+// * 请求地址:POST http://{baseUrl}/{indexName}/{typeName}/_search +// */ +// public JSONObject search(String indexName, String typeName, JSONObject queryObject) { +// String url = this.getBaseUrl(indexName, typeName).append("/_search").toString(); +// +// log.info("url:" + url + " ,search: " + queryObject.toJSONString()); +// JSONObject res = RestUtil.post(url, queryObject); +// log.info("url:" + url + " ,return res: \n" + res.toJSONString()); +// return res; +// } +// +// /** +// * @param source (源滤波器)指定返回的字段,传null返回所有字段 +// * @param query +// * @param from 从第几条数据开始 +// * @param size 返回条目数 +// * @return { "query": query } +// */ +// public JSONObject buildQuery(List source, JSONObject query, int from, int size) { +// JSONObject json = new JSONObject(); +// if (source != null) { +// json.put("_source", source); +// } +// json.put("query", query); +// json.put("from", from); +// json.put("size", size); +// return json; +// } +// +// /** +// * @return { "bool" : { "must": must, "must_not": mustNot, "should": should } } +// */ +// public JSONObject buildBoolQuery(JSONArray must, JSONArray mustNot, JSONArray should) { +// JSONObject bool = new JSONObject(); +// if (must != null) { +// bool.put("must", must); +// } +// if (mustNot != null) { +// bool.put("must_not", mustNot); +// } +// if (should != null) { +// bool.put("should", should); +// } +// JSONObject json = new JSONObject(); +// json.put("bool", bool); +// return json; +// } +// +// /** +// * @param field 要查询的字段 +// * @param args 查询参数,参考: *哈哈* OR *哒* NOT *呵* OR *啊* +// * @return +// */ +// public JSONObject buildQueryString(String field, String... args) { +// if (field == null) { +// return null; +// } +// StringBuilder sb = new StringBuilder(field).append(":("); +// if (args != null) { +// for (String arg : args) { +// sb.append(arg).append(" "); +// } +// } +// sb.append(")"); +// return this.buildQueryString(sb.toString()); +// } +// +// /** +// * @return { "query_string": { "query": query } } +// */ +// public JSONObject buildQueryString(String query) { +// JSONObject queryString = new JSONObject(); +// queryString.put("query", query); +// JSONObject json = new JSONObject(); +// json.put("query_string", queryString); +// return json; +// } +// +// /** +// * @param field 查询字段 +// * @param min 最小值 +// * @param max 最大值 +// * @param containMin 范围内是否包含最小值 +// * @param containMax 范围内是否包含最大值 +// * @return { "range" : { field : { 『 "gt『e』?containMin" : min 』?min!=null , 『 "lt『e』?containMax" : max 』}} } +// */ +// public JSONObject buildRangeQuery(String field, Object min, Object max, boolean containMin, boolean containMax) { +// JSONObject inner = new JSONObject(); +// if (min != null) { +// if (containMin) { +// inner.put("gte", min); +// } else { +// inner.put("gt", min); +// } +// } +// if (max != null) { +// if (containMax) { +// inner.put("lte", max); +// } else { +// inner.put("lt", max); +// } +// } +// JSONObject range = new JSONObject(); +// range.put(field, inner); +// JSONObject json = new JSONObject(); +// json.put("range", range); +// return json; +// } +// +//} +// diff --git a/digital-common/digital-util/src/main/java/digital/util/es/QueryStringBuilder.java b/digital-common/digital-util/src/main/java/digital/util/es/QueryStringBuilder.java new file mode 100644 index 0000000..caecc94 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/es/QueryStringBuilder.java @@ -0,0 +1,98 @@ +//package digital.util.util.es; +// +///** +// * 用于创建 ElasticSearch 的 queryString +// * +// * @author sunjianlei +// */ +//public class QueryStringBuilder { +// +// StringBuilder builder; +// +// public QueryStringBuilder(String field, String str, boolean not, boolean addQuot) { +// builder = this.createBuilder(field, str, not, addQuot); +// } +// +// public QueryStringBuilder(String field, String str, boolean not) { +// builder = this.createBuilder(field, str, not, true); +// } +// +// /** +// * 创建 StringBuilder +// * +// * @param field +// * @param str +// * @param not 是否是不匹配 +// * @param addQuot 是否添加双引号 +// * @return +// */ +// public StringBuilder createBuilder(String field, String str, boolean not, boolean addQuot) { +// StringBuilder sb = new StringBuilder(field).append(":("); +// if (not) { +// sb.append(" NOT "); +// } +// this.addQuotEffect(sb, str, addQuot); +// return sb; +// } +// +// public QueryStringBuilder and(String str) { +// return this.and(str, true); +// } +// +// public QueryStringBuilder and(String str, boolean addQuot) { +// builder.append(" AND "); +// this.addQuot(str, addQuot); +// return this; +// } +// +// public QueryStringBuilder or(String str) { +// return this.or(str, true); +// } +// +// public QueryStringBuilder or(String str, boolean addQuot) { +// builder.append(" OR "); +// this.addQuot(str, addQuot); +// return this; +// } +// +// public QueryStringBuilder not(String str) { +// return this.not(str, true); +// } +// +// public QueryStringBuilder not(String str, boolean addQuot) { +// builder.append(" NOT "); +// this.addQuot(str, addQuot); +// return this; +// } +// +// /** +// * 添加双引号(模糊查询,不能加双引号) +// */ +// private QueryStringBuilder addQuot(String str, boolean addQuot) { +// return this.addQuotEffect(this.builder, str, addQuot); +// } +// +// /** +// * 是否在两边加上双引号 +// * @param builder +// * @param str +// * @param addQuot +// * @return +// */ +// private QueryStringBuilder addQuotEffect(StringBuilder builder, String str, boolean addQuot) { +// if (addQuot) { +// builder.append('"'); +// } +// builder.append(str); +// if (addQuot) { +// builder.append('"'); +// } +// return this; +// } +// +// @Override +// public String toString() { +// return builder.append(")").toString(); +// } +// +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBoot401Exception.java b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBoot401Exception.java new file mode 100644 index 0000000..19a13f3 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBoot401Exception.java @@ -0,0 +1,23 @@ +package digital.util.exception; + +/** + * @Description: smcp自定义401异常 + * @author: smcp + */ +public class JeecgBoot401Exception extends RuntimeException { + private static final long serialVersionUID = 1L; + + public JeecgBoot401Exception(String message){ + super(message); + } + + public JeecgBoot401Exception(Throwable cause) + { + super(cause); + } + + public JeecgBoot401Exception(String message, Throwable cause) + { + super(message,cause); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootException.java b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootException.java new file mode 100644 index 0000000..a60933d --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootException.java @@ -0,0 +1,23 @@ +package digital.util.exception; + +/** + * @Description: smcp自定义异常 + * @author: smcp + */ +public class JeecgBootException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public JeecgBootException(String message){ + super(message); + } + + public JeecgBootException(Throwable cause) + { + super(cause); + } + + public JeecgBootException(String message,Throwable cause) + { + super(message,cause); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootExceptionHandler.java b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootExceptionHandler.java new file mode 100644 index 0000000..b53ce13 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgBootExceptionHandler.java @@ -0,0 +1,212 @@ +package digital.util.exception; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.authz.AuthorizationException; +import org.apache.shiro.authz.UnauthorizedException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.DuplicateKeyException; +//import org.springframework.data.redis.connection.PoolException; +import org.springframework.data.redis.connection.PoolException; +import org.springframework.http.HttpStatus; +import org.springframework.validation.BindException; +import org.springframework.validation.BindingResult; +import org.springframework.validation.FieldError; +import org.springframework.validation.ObjectError; +import org.springframework.web.HttpRequestMethodNotSupportedException; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import org.springframework.web.multipart.MaxUploadSizeExceededException; +import org.springframework.web.servlet.NoHandlerFoundException; +import digital.base.enums.SentinelErrorInfoEnum; +import digital.base.vo.Result; + +import javax.xml.bind.ValidationException; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 异常处理器 + * + * @Author scott + * @Date 2019 + */ +@RestControllerAdvice +@Slf4j +public class JeecgBootExceptionHandler { + + //绑普通字符串没绑好异常 + @ExceptionHandler(BindException.class) + public Result handleBindException(BindException e){ + log.error("参数不匹配",e); + //获取参数绑定结果(包括绑定错误信息) + BindingResult bindingResult = e.getBindingResult(); + //获取属性错误集合 + List fieldErrorList = bindingResult.getFieldErrors(); + String errMsg = fieldErrorList.stream() + .map(fieldError->fieldError.getField()+":"+fieldError.getDefaultMessage()) + .collect(Collectors.joining(",")); + return Result.error(errMsg); + } + /** + * 方法参数校验 + */ + @ExceptionHandler(MethodArgumentNotValidException.class) + public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { + log.error(e.getMessage()); + List allErrors = e.getBindingResult().getAllErrors(); + String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";")); + return Result.error(message); + } +// @ExceptionHandler(BeanPropertyBindingResult.class) +// public String handleBeanPropertyBindingResult(BeanPropertyBindingResult exception) { +// // 处理BeanPropertyBindingResult异常的逻辑 +// // 可以获取异常信息、错误码等,并返回一个适当的响应给客户端 +// return "发生验证错误,请检查输入数据是否符合要求"; +// } +// @ExceptionHandler(BeanPropertyBindingResult.class) +// public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { +// log.error(e.getMessage()); +// List allErrors = e.getBindingResult().getAllErrors(); +// String message = allErrors.stream().map(s -> s.getDefaultMessage()).collect(Collectors.joining(";")); +// return Result.error(message); +// } + + + /** + * ValidationException + */ + @ExceptionHandler(ValidationException.class) + public Result handleValidationException(ValidationException e) { + log.error(e.getMessage(), e); + return Result.error(e.getCause().getMessage()); + } + + /** + * ConstraintViolationException + */ +// @ExceptionHandler(ConstraintViolationException.class) +// public Result handleConstraintViolationException(ConstraintViolationException e) { +// +// Set> violations = e.getConstraintViolations(); +// if (violations.size() > 0) { +// List list = new ArrayList<>(); +// for (ConstraintViolation violation : violations) { +// list.add(violation.getMessage()); +// } +// +// if (!list.isEmpty()) { +// log.error(list.toString()); +// return Result.error(list.toString()); +// } +// } +// return Result.error(e.getMessage()); +// } + + /** + * 处理自定义异常 + */ + @ExceptionHandler(JeecgBootException.class) + public Result handleJeecgBootException(JeecgBootException e){ + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + + /** + * 处理自定义微服务异常 + */ + @ExceptionHandler(JeecgCloudException.class) + public Result handleJeecgCloudException(JeecgCloudException e){ + log.error(e.getMessage(), e); + return Result.error(e.getMessage()); + } + + /** + * 处理自定义异常 + */ + @ExceptionHandler(JeecgBoot401Exception.class) + @ResponseStatus(HttpStatus.UNAUTHORIZED) + public Result handleJeecgBoot401Exception(JeecgBoot401Exception e){ + log.error(e.getMessage(), e); + return new Result(401,e.getMessage()); + } + + @ExceptionHandler(NoHandlerFoundException.class) + public Result handlerNoFoundException(Exception e) { + log.error(e.getMessage(), e); + return Result.error(404, "路径不存在,请检查路径是否正确"); + } + + @ExceptionHandler(DuplicateKeyException.class) + public Result handleDuplicateKeyException(DuplicateKeyException e){ + log.error(e.getMessage(), e); + return Result.error("数据库中已存在该记录"); + } + + @ExceptionHandler({UnauthorizedException.class, AuthorizationException.class}) + public Result handleAuthorizationException(AuthorizationException e){ + log.error(e.getMessage(), e); + return Result.noauth("没有权限,请联系管理员授权"); + } + + @ExceptionHandler(Exception.class) + public Result handleException(Exception e){ + log.error(e.getMessage(), e); + //update-begin---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常 + Throwable throwable = e.getCause(); + SentinelErrorInfoEnum errorInfoEnum = SentinelErrorInfoEnum.getErrorByException(throwable); + if (ObjectUtil.isNotEmpty(errorInfoEnum)) { + return Result.error(errorInfoEnum.getError()); + } + //update-end---author:zyf ---date:20220411 for:处理Sentinel限流自定义异常 + return Result.error("操作失败,"+e.getMessage()); + } + + /** + * @Author 政辉 + * @param e + * @return + */ + @ExceptionHandler(HttpRequestMethodNotSupportedException.class) + public Result httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){ + StringBuffer sb = new StringBuffer(); + sb.append("不支持"); + sb.append(e.getMethod()); + sb.append("请求方法,"); + sb.append("支持以下"); + String [] methods = e.getSupportedMethods(); + if(methods!=null){ + for(String str:methods){ + sb.append(str); + sb.append("、"); + } + } + log.error(sb.toString(), e); + //return Result.error("没有权限,请联系管理员授权"); + return Result.error(405,sb.toString()); + } + + /** + * spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException + */ + @ExceptionHandler(MaxUploadSizeExceededException.class) + public Result handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) { + log.error(e.getMessage(), e); + return Result.error("文件大小超出10MB限制, 请压缩或降低文件质量! "); + } + + @ExceptionHandler(DataIntegrityViolationException.class) + public Result handleDataIntegrityViolationException(DataIntegrityViolationException e) { + log.error(e.getMessage(), e); + return Result.error("字段太长,超出数据库字段的长度"); + } + + @ExceptionHandler(PoolException.class) + public Result handlePoolException(PoolException e) { + log.error(e.getMessage(), e); + return Result.error("Redis 连接异常!"); + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/exception/JeecgCloudException.java b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgCloudException.java new file mode 100644 index 0000000..bcd76a5 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/exception/JeecgCloudException.java @@ -0,0 +1,15 @@ +package digital.util.exception; + +/** + * @Description: jeecg-cloud自定义异常 + * @Author: zyf + * @Date: 2022-05-30 + */ +public class JeecgCloudException extends RuntimeException { + private static final long serialVersionUID = 1L; + + public JeecgCloudException(String message) { + super(message); + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/filter/FileTypeFilter.java b/digital-common/digital-util/src/main/java/digital/util/filter/FileTypeFilter.java new file mode 100644 index 0000000..7f1d9f6 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/filter/FileTypeFilter.java @@ -0,0 +1,164 @@ +package digital.util.filter; + +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import java.io.InputStream; +import java.util.HashMap; +import java.util.Iterator; + +/** + * @Description: TODO + * @author: lsq + * @date: 2021年08月09日 15:29 + */ +public class FileTypeFilter { + + /**文件后缀*/ + private static String[] forbidType = {"jsp","php"}; + + /**初始化文件头类型,不够的自行补充*/ + final static HashMap FILE_TYPE_MAP = new HashMap<>(); + + static { + FILE_TYPE_MAP.put("3c25402070616765206c", "jsp"); + FILE_TYPE_MAP.put("3c3f7068700a0a2f2a2a0a202a205048", "php"); + /* fileTypeMap.put("ffd8ffe000104a464946", "jpg"); + fileTypeMap.put("89504e470d0a1a0a0000", "png"); + fileTypeMap.put("47494638396126026f01", "gif"); + fileTypeMap.put("49492a00227105008037", "tif"); + fileTypeMap.put("424d228c010000000000", "bmp"); + fileTypeMap.put("424d8240090000000000", "bmp"); + fileTypeMap.put("424d8e1b030000000000", "bmp"); + fileTypeMap.put("41433130313500000000", "dwg"); + fileTypeMap.put("3c21444f435459504520", "html"); + fileTypeMap.put("3c21646f637479706520", "htm"); + fileTypeMap.put("48544d4c207b0d0a0942", "css"); + fileTypeMap.put("696b2e71623d696b2e71", "js"); + fileTypeMap.put("7b5c727466315c616e73", "rtf"); + fileTypeMap.put("38425053000100000000", "psd"); + fileTypeMap.put("46726f6d3a203d3f6762", "eml"); + fileTypeMap.put("d0cf11e0a1b11ae10000", "doc"); + fileTypeMap.put("5374616E64617264204A", "mdb"); + fileTypeMap.put("252150532D41646F6265", "ps"); + fileTypeMap.put("255044462d312e350d0a", "pdf"); + fileTypeMap.put("2e524d46000000120001", "rmvb"); + fileTypeMap.put("464c5601050000000900", "flv"); + fileTypeMap.put("00000020667479706d70", "mp4"); + fileTypeMap.put("49443303000000002176", "mp3"); + fileTypeMap.put("000001ba210001000180", "mpg"); + fileTypeMap.put("3026b2758e66cf11a6d9", "wmv"); + fileTypeMap.put("52494646e27807005741", "wav"); + fileTypeMap.put("52494646d07d60074156", "avi"); + fileTypeMap.put("4d546864000000060001", "mid"); + fileTypeMap.put("504b0304140000000800", "zip"); + fileTypeMap.put("526172211a0700cf9073", "rar"); + fileTypeMap.put("235468697320636f6e66", "ini"); + fileTypeMap.put("504b03040a0000000000", "jar"); + fileTypeMap.put("4d5a9000030000000400", "exe"); + fileTypeMap.put("3c25402070616765206c", "jsp"); + fileTypeMap.put("4d616e69666573742d56", "mf"); + fileTypeMap.put("3c3f786d6c2076657273", "xml"); + fileTypeMap.put("494e5345525420494e54", "sql"); + fileTypeMap.put("7061636b616765207765", "java"); + fileTypeMap.put("406563686f206f66660d", "bat"); + fileTypeMap.put("1f8b0800000000000000", "gz"); + fileTypeMap.put("6c6f67346a2e726f6f74", "properties"); + fileTypeMap.put("cafebabe0000002e0041", "class"); + fileTypeMap.put("49545346030000006000", "chm"); + fileTypeMap.put("04000000010000001300", "mxp"); + fileTypeMap.put("504b0304140006000800", "docx"); + fileTypeMap.put("6431303a637265617465", "torrent"); + fileTypeMap.put("6D6F6F76", "mov"); + fileTypeMap.put("FF575043", "wpd"); + fileTypeMap.put("CFAD12FEC5FD746F", "dbx"); + fileTypeMap.put("2142444E", "pst"); + fileTypeMap.put("AC9EBD8F", "qdf"); + fileTypeMap.put("E3828596", "pwl"); + fileTypeMap.put("2E7261FD", "ram");*/ + } + + /** + * @param fileName + * @return String + * @description 通过文件后缀名获取文件类型 + */ + private static String getFileTypeBySuffix(String fileName) { + return fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); + } + + /** + * 文件类型过滤 + * + * @param file + */ + public static void fileTypeFilter(MultipartFile file) throws Exception { + String suffix = getFileType(file); + for (String type : forbidType) { + if (type.contains(suffix)) { + throw new Exception("上传失败,文件类型异常:" + suffix); + } + } + } + + /** + * 通过读取文件头部获得文件类型 + * + * @param file + * @return 文件类型 + * @throws Exception + */ + + private static String getFileType(MultipartFile file) throws Exception { + String fileExtendName = null; + InputStream is; + try { + //is = new FileInputStream(file); + is = file.getInputStream(); + byte[] b = new byte[10]; + is.read(b, 0, b.length); + String fileTypeHex = String.valueOf(bytesToHexString(b)); + Iterator keyIter = FILE_TYPE_MAP.keySet().iterator(); + while (keyIter.hasNext()) { + String key = keyIter.next(); + // 验证前5个字符比较 + if (key.toLowerCase().startsWith(fileTypeHex.toLowerCase().substring(0, 5)) + || fileTypeHex.toLowerCase().substring(0, 5).startsWith(key.toLowerCase())) { + fileExtendName = FILE_TYPE_MAP.get(key); + break; + } + } + // 如果不是上述类型,则判断扩展名 + if (StringUtils.isBlank(fileExtendName)) { + String fileName = file.getOriginalFilename(); + return getFileTypeBySuffix(fileName); + } + is.close(); + return fileExtendName; + } catch (Exception exception) { + throw new Exception(exception.getMessage(), exception); + } + } + + /** + * 获得文件头部字符串 + * + * @param src + * @return + */ + private static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/filter/StrAttackFilter.java b/digital-common/digital-util/src/main/java/digital/util/filter/StrAttackFilter.java new file mode 100644 index 0000000..0e54c9c --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/filter/StrAttackFilter.java @@ -0,0 +1,25 @@ +package digital.util.filter; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +/** + * 文件上传字符串过滤特殊字符 + * @author: smcp + */ +public class StrAttackFilter { + + public static String filter(String str) throws PatternSyntaxException { + // 清除掉所有特殊字符 + String regEx = "[`_《》~!@#$%^&*()+=|{}':;',\\[\\].<>?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]"; + Pattern p = Pattern.compile(regEx); + Matcher m = p.matcher(str); + return m.replaceAll("").trim(); + } + +// public static void main(String[] args) { +// String filter = filter("@#jeecg/《》【bo】¥%……&*(o))))!@t<>,.,/?'\'~~`"); +// System.out.println(filter); +// } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/oss/OssBootUtil.java b/digital-common/digital-util/src/main/java/digital/util/oss/OssBootUtil.java new file mode 100644 index 0000000..41ea05b --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/oss/OssBootUtil.java @@ -0,0 +1,655 @@ +package digital.util.oss; + +import cn.hutool.core.io.FileUtil; +import com.alibaba.fastjson.JSONObject; +import com.aliyun.oss.*; +import com.aliyun.oss.common.auth.DefaultCredentialProvider; +import com.aliyun.oss.common.comm.Protocol; +import com.aliyun.oss.common.utils.BinaryUtil; +import com.aliyun.oss.model.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.apache.tomcat.util.http.fileupload.FileItemStream; +import org.springframework.web.multipart.MultipartFile; +import digital.base.vo.LoginUser; +import digital.util.util.CommonUtils; +import digital.util.util.oConvertUtils; + +import java.io.*; +import java.net.URL; +import java.util.Date; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.UUID; + +/** + * @Description: 阿里云 oss 上传工具类(高依赖版) + * @Date: 2019/5/10 + */ +@Slf4j +public class OssBootUtil { + + private static String endPoint; + private static String accessKeyId; + private static String accessKeySecret; + private static String bucketName; + private static String staticDomain; + private static String callBackUrl; + + public static void setEndPoint(String endPoint) { + OssBootUtil.endPoint = endPoint; + } + + public static void setAccessKeyId(String accessKeyId) { + OssBootUtil.accessKeyId = accessKeyId; + } + + public static void setAccessKeySecret(String accessKeySecret) { + OssBootUtil.accessKeySecret = accessKeySecret; + } + + public static void setBucketName(String bucketName) { + OssBootUtil.bucketName = bucketName; + } + + public static void setStaticDomain(String staticDomain) { + OssBootUtil.staticDomain = staticDomain; + } + + public static String getStaticDomain() { + return staticDomain; + } + + /** + * oss 工具客户端 + */ + private static OSSClient ossClient = null; + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String uploadOssKsf(MultipartFile file, String fileDir,String customBucket) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + try { + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + String fileName = UserUtil.getId() + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream()); + return fileUrl.toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String uploadOssKsf(File file, String fileDir, String customBucket) { + return uploadOssKsf(file,fileDir,customBucket,""); + } + + public static String uploadOssVideo(File file, String fileDir,String newFileName) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getName(); + orgName = CommonUtils.getFileName(orgName); + String fileName = newFileName; + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), FileUtil.getInputStream(file)); + // 设置权限(公开读) + ossClient.setObjectAcl(newBucket,fileUrl.toString(), CannedAccessControlList.PublicRead); + if (result != null) { +// log.info("------OSS文件上传成功------" + fileUrl); + } + return fileUrl.toString(); + } + + + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String uploadOssKsf(File file, String fileDir, String customBucket,String preFix) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getName(); + orgName = CommonUtils.getFileName(orgName); + String fileName = preFix+UserUtil.getId() + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), FileUtil.getInputStream(file)); + return fileUrl.toString(); + } + + + public static String uploadOssMat(MultipartFile file, String fileDir,String customBucket,String newFileName) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + try { + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream()); + return fileUrl.toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String uploadOssMed(MultipartFile file, String fileDir,String customBucket) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + try { + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream()); + return fileUrl.toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + public static String uploadOssVideo(MultipartFile file, String fileDir,String customBucket) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + try { + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getName(); + orgName = CommonUtils.getFileName(orgName); + String fileName = System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream()); + return fileUrl.toString(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String upload(MultipartFile file, String fileDir,String customBucket) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(customBucket)){ + newBucket = customBucket; + } + try { + //判断桶是否存在,不存在则创建桶 + if(!ossClient.doesBucketExist(newBucket)){ + ossClient.createBucket(newBucket); + } + // 获取文件名 + String orgName = file.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + String fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.indexOf(".")); + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + newBucket + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(newBucket, fileUrl.toString(), file.getInputStream()); + // 设置权限(公开读) + ossClient.setObjectAcl(newBucket,fileUrl.toString(), CannedAccessControlList.PublicRead); + if (result != null) { +// log.info("------OSS文件上传成功------" + fileUrl); + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + return FILE_URL; + } + + /** + * 文件上传 + * @param file + * @param fileDir + * @return + */ + public static String upload(MultipartFile file, String fileDir) { + return upload(file, fileDir,null); + } + + /** + * 上传文件至阿里云 OSS + * 文件上传成功,返回文件完整访问路径 + * 文件上传失败,返回 null + * + * @param file 待上传文件 + * @param fileDir 文件保存目录 + * @return oss 中的相对文件路径 + */ + public static String upload(FileItemStream file, String fileDir) { + String FILE_URL = null; + initOSS(endPoint, accessKeyId, accessKeySecret); + StringBuilder fileUrl = new StringBuilder(); + try { + String suffix = file.getName().substring(file.getName().lastIndexOf('.')); + String fileName = UUID.randomUUID().toString().replace("-", "") + suffix; + if (!fileDir.endsWith("/")) { + fileDir = fileDir.concat("/"); + } + fileUrl = fileUrl.append(fileDir + fileName); + + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + fileUrl; + } else { + FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(bucketName, fileUrl.toString(), file.openStream()); + // 设置权限(公开读) + ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); + if (result != null) { +// log.info("------OSS文件上传成功------" + fileUrl); + } + } catch (IOException e) { + e.printStackTrace(); + return null; + } + return FILE_URL; + } + + /** + * 删除文件 + * @param url + */ + public static void deleteUrl(String url) { + deleteUrl(url,null); + } + + /** + * 删除文件 + * @param url + */ + public static void deleteUrl(String url,String bucket) { + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(bucket)){ + newBucket = bucket; + } + String bucketUrl = ""; + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + bucketUrl = staticDomain + "/" ; + } else { + bucketUrl = "https://" + newBucket + "." + endPoint + "/"; + } + url = url.replace(bucketUrl,""); + ossClient.deleteObject(newBucket, url); + } + + /** + * 删除文件 + * @param fileName + */ + public static void delete(String fileName) { + ossClient.deleteObject(bucketName, fileName); + } + + /** + * 获取文件流 + * @param objectName + * @param bucket + * @return + */ + public static InputStream getOssFile(String objectName,String bucket){ + InputStream inputStream = null; + try{ + String newBucket = bucketName; + if(oConvertUtils.isNotEmpty(bucket)){ + newBucket = bucket; + } + initOSS(endPoint, accessKeyId, accessKeySecret); +// initOSS("oss-accelerate.aliyuncs.com", "LTAI5tFigifExsV2BxWYCyd1", "khvitMKIOMDehLf7QouuZATgcDl75k"); + OSSObject ossObject = ossClient.getObject(newBucket,objectName); + inputStream = new BufferedInputStream(ossObject.getObjectContent()); + }catch (Exception e){ + log.info("文件获取失败" + e.getMessage()); + } + return inputStream; + } + + /** + * 获取文件流 + * @param objectName + * @return + */ + public static InputStream getOssFile(String objectName){ + return getOssFile(objectName,null); + } + + /** + * 获取文件外链 + * @param bucketName + * @param objectName + * @param expires + * @return + */ +// public static String getObjectURL(String bucketName, String objectName, Date expires) { +// initOSS(endPoint, accessKeyId, accessKeySecret); +// try{ +// if(ossClient.doesObjectExist(bucketName,objectName)){ +// URL url = ossClient.generatePresignedUrl(bucketName,objectName,expires); +// String urlString=""; +// urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain); +// urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain); +// return urlString; +// } +// }catch (Exception e){ +// log.info("文件路径获取失败" + e.getMessage()); +// } +// return null; +// } + + /** + * 获取文件外链 + * @param bucketName + * @param objectName + * @param expires + * @return + */ + public static String getObjectURL(String bucketName, String objectName, Date expires) { + initOSS(endPoint, accessKeyId, accessKeySecret); + try{ + if(ossClient.doesObjectExist(bucketName,objectName)){ + // 设置URL过期时间为10年 3600l* 1000*24*365*10 + Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20); + URL url = ossClient.generatePresignedUrl(bucketName,objectName,expiration); + String urlString=""; + urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain); + urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain); + return urlString; + } + }catch (Exception e){ + log.info("文件路径获取失败" + e.getMessage()); + } + return null; + } + + public static String getDigitalObjectURL(String bucketName, String objectName, Date expires) { + initOSS(endPoint, accessKeyId, accessKeySecret); + try{ + if(ossClient.doesObjectExist(bucketName,objectName)){ + // 设置URL过期时间为10年 3600l* 1000*24*365*10 + Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20); + URL url = ossClient.generatePresignedUrl(bucketName,objectName,expiration); + String urlString=staticDomain+"/"+objectName; +// String urlString=""; +// urlString = url.toString().replace("http://"+bucketName+"."+endPoint,staticDomain); +// urlString = urlString.toString().replace("https://"+bucketName+"."+endPoint,staticDomain); + return urlString; + } + }catch (Exception e){ + log.info("文件路径获取失败" + e.getMessage()); + } + return null; + } + + public static String getObjectThumbnailURL(String bucketName, String objectName) { + initOSS(endPoint, accessKeyId, accessKeySecret); + try { + if (ossClient.doesObjectExist(bucketName, objectName)) { + String style = "image/resize,h_250,m_lfit"; + GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET); + Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 20); + req.setExpiration(expiration); + req.setProcess(style); + String urlString = ""; + URL signedUrl = ossClient.generatePresignedUrl(req); + urlString = signedUrl.toString().replace("http://" + bucketName + "." + endPoint, staticDomain); + urlString = urlString.toString().replace("https://" + bucketName + "." + endPoint, staticDomain); + return urlString; + } + }catch (Exception e){ + log.info("文件路径获取失败" + e.getMessage()); + } + return null; + } + + /** + * 初始化 oss 客户端 + * + * @return + */ + public static OSSClient initOSS(String endpoint, String accessKeyId, String accessKeySecret) { + if (ossClient == null) { + ClientConfiguration clientConfiguration = new ClientConfiguration(); + clientConfiguration.setProtocol(Protocol.HTTPS); + ossClient = new OSSClient(endpoint, + new DefaultCredentialProvider(accessKeyId, accessKeySecret),clientConfiguration + ); + } + return ossClient; + } + + + /** + * 上传文件到oss + * @param stream + * @param relativePath + * @return + */ + public static String upload(InputStream stream, String relativePath) { + String FILE_URL = null; + String fileUrl = relativePath; + initOSS(endPoint, accessKeyId, accessKeySecret); + if (oConvertUtils.isNotEmpty(staticDomain) && staticDomain.toLowerCase().startsWith("http")) { + FILE_URL = staticDomain + "/" + relativePath; + } else { + FILE_URL = "https://" + bucketName + "." + endPoint + "/" + fileUrl; + } + PutObjectResult result = ossClient.putObject(bucketName, relativePath,stream); + // 设置权限(公开读) + ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead); + if (result != null) { +// log.info("------OSS文件上传成功------" + fileUrl); + } + return FILE_URL; + } + + + public static void setCallBackUrl(String callBackUrl) { + OssBootUtil.callBackUrl = callBackUrl; + } + + public static String getCallBackUrl() { + return callBackUrl; + } + + /** + * // String accessId = "LTAI5tRWhHy73uXBWHgcsC69"; // 请填写您的AccessKeyId。 + * // String accessKey = "qNepcIbYfWTLoQnCgOh8388cUVMZQ6"; // 请填写您的AccessKeySecret。 + * // String endpoint = "oss-cn-beijing.aliyuncs.com"; // 请填写您的 endpoint。 + * // String bucket = "hnmedicineoss"; // 请填写您的 bucketname 。 + * // String host = "http://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint + * // // callbackUrl为 上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。 + * // String callbackUrl = "https://hnmedicine.crabholder.cn/claimbyself/insurance/user/v1/doCallBackOss"; + * + + * @param dir + * @param fileName + * @return + * @throws UnsupportedEncodingException + */ + public static Map getStatsToken(String dir, String fileName) throws UnsupportedEncodingException { + OSSClient client = initOSS(endPoint, accessKeyId, accessKeySecret); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + long expireTime = 300; + long expireEndTime = System.currentTimeMillis() + expireTime * 1000; + java.sql.Date expiration = new java.sql.Date(expireEndTime); + PolicyConditions policyConds = new PolicyConditions(); + policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000); + policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir); + String postPolicy = client.generatePostPolicy(expiration, policyConds); + byte[] binaryData = postPolicy.getBytes("utf-8"); + String encodedPolicy = BinaryUtil.toBase64String(binaryData); + String postSignature = client.calculatePostSignature(postPolicy); + Map respMap = new LinkedHashMap(); + respMap.put("accessKeyId", accessKeyId); + respMap.put("policy", encodedPolicy); + respMap.put("signature", postSignature); + respMap.put("dir", dir); + respMap.put("host", staticDomain); + respMap.put("expire", String.valueOf(expireEndTime / 1000)); + // respMap.put("expire", formatISO8601Date(expiration)); + JSONObject jasonCallback = new JSONObject(); + jasonCallback.put("callbackUrl", callBackUrl); + jasonCallback.put("callbackBody", + "ossFilePath=${object}&object=${object}&size=${size}&mimeType=${mimeType}&height=" + + "${imageInfo.height}&width=${imageInfo.width}&fileType=1&fileName="+fileName+"&userId="+loginUser.getId()); + jasonCallback.put("callbackBodyType", "application/x-www-form-urlencoded"); + String base64CallbackBody = BinaryUtil.toBase64String(jasonCallback.toString().getBytes()); + respMap.put("callback", base64CallbackBody); + return respMap; + } + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/oss/OssUploadWithThirdPartySTS.java b/digital-common/digital-util/src/main/java/digital/util/oss/OssUploadWithThirdPartySTS.java new file mode 100644 index 0000000..6490734 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/oss/OssUploadWithThirdPartySTS.java @@ -0,0 +1,22 @@ +package digital.util.oss; + +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.PutObjectRequest; + +public class OssUploadWithThirdPartySTS { + public static void main(String[] args) { + // 第三方STS提供的临时凭证信息 + String tempAccessKeyId = "临时AccessKeyId"; + String tempAccessKeySecret = "临时AccessKeySecret"; + String securityToken = "安全令牌Token"; + String ossEndpoint = "OSS的Endpoint"; // 例如:oss-cn-hangzhou.aliyuncs.com + String ossBucketName = "你的OSS Bucket名称"; + + + + System.out.println("文件上传成功!"); + + + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/oss/UserUtil.java b/digital-common/digital-util/src/main/java/digital/util/oss/UserUtil.java new file mode 100644 index 0000000..552504b --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/oss/UserUtil.java @@ -0,0 +1,20 @@ +package digital.util.oss; + +import org.apache.shiro.SecurityUtils; +import digital.base.vo.LoginUser; + +/** + * U CAN GET A CRAB WHEN U MEET US! + * IF GET A QUESTION,PLEASE CONTACT US: + * WEBSITE: www.crabholder.cn www.crabholder.com + * EMAIL:crabholder@163.com. + * CREATED ON 2020/7/13! + */ +public class UserUtil { + public static LoginUser getLoginUser() { + return (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } + public static String getId() { + return ((LoginUser) SecurityUtils.getSubject().getPrincipal()).getId(); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/AbstractQueryBlackListHandler.java b/digital-common/digital-util/src/main/java/digital/util/security/AbstractQueryBlackListHandler.java new file mode 100644 index 0000000..e04bb65 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/AbstractQueryBlackListHandler.java @@ -0,0 +1,174 @@ +package digital.util.security; + +import lombok.extern.slf4j.Slf4j; + +import java.util.*; + +/** + * 查询表/字段 黑名单处理 + * @Author taoYan + * @Date 2022/3/17 11:21 + **/ +@Slf4j +public abstract class AbstractQueryBlackListHandler { + + /** + * key-表名 + * value-字段名,多个逗号隔开 + * 两种配置方式-- 全部配置成小写 + * ruleMap.put("sys_user", "*")sys_user所有的字段不支持查询 + * ruleMap.put("sys_user", "username,password")sys_user中的username和password不支持查询 + */ + public static Map ruleMap = new HashMap<>(); + + static { + ruleMap.put("sys_user", "password,salt"); + } + + + /** + * 根据 sql语句 获取表和字段信息,需要到具体的实现类重写此方法- + * 不同的场景 处理可能不太一样 需要自定义,但是返回值确定 + * @param sql + * @return + */ + protected abstract List getQueryTableInfo(String sql); + + + /** + * 校验sql语句 成功返回true + * @param sql + * @return + */ + public boolean isPass(String sql) { + List list = this.getQueryTableInfo(sql.toLowerCase()); + if(list==null){ + return true; + } + log.info("--获取sql信息--", list.toString()); + boolean flag = true; + for (QueryTable table : list) { + String name = table.getName(); + String fieldString = ruleMap.get(name); + // 有没有配置这张表 + if (fieldString != null) { + if ("*".equals(fieldString) || table.isAll()) { + flag = false; + log.warn("sql黑名单校验,表【"+name+"】禁止查询"); + break; + } else if (table.existSameField(fieldString)) { + flag = false; + break; + } + + } + } + return flag; + } + + /** + * 查询的表的信息 + */ + protected class QueryTable { + //表名 + private String name; + //表的别名 + private String alias; + // 字段名集合 + private Set fields; + // 是否查询所有字段 + private boolean all; + + public QueryTable() { + } + + public QueryTable(String name, String alias) { + this.name = name; + this.alias = alias; + this.all = false; + this.fields = new HashSet<>(); + } + + public void addField(String field) { + this.fields.add(field); + } + + public String getName() { + return name; + } + + public Set getFields() { + return new HashSet<>(fields); + } + + public void setName(String name) { + this.name = name; + } + + public void setFields(Set fields) { + this.fields = fields; + } + + public String getAlias() { + return alias; + } + + public void setAlias(String alias) { + this.alias = alias; + } + + public boolean isAll() { + return all; + } + + public void setAll(boolean all) { + this.all = all; + } + + /** + * 判断是否有相同字段 + * + * @param fieldString + * @return + */ + public boolean existSameField(String fieldString) { + String[] arr = fieldString.split(","); + for (String exp : fields) { + for (String config : arr) { + if (exp.equals(config)) { + // 非常明确的列直接比较 + log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询"); + return true; + } else { + // 使用表达式的列 只能判读字符串包含了 + String aliasColumn = config; + if (alias != null && alias.length() > 0) { + aliasColumn = alias + "." + config; + } + if (exp.indexOf(aliasColumn) > 0) { + log.warn("sql黑名单校验,表【"+name+"】中字段【"+config+"】禁止查询"); + return true; + } + } + } + } + return false; + } + + @Override + public String toString() { + return "QueryTable{" + + "name='" + name + '\'' + + ", alias='" + alias + '\'' + + ", fields=" + fields + + ", all=" + all + + '}'; + } + } + + public String getError(){ + // TODO + return "sql黑名单校验不通过,请联系管理员!"; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/SecurityTools.java b/digital-common/digital-util/src/main/java/digital/util/security/SecurityTools.java new file mode 100644 index 0000000..cdaabe5 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/SecurityTools.java @@ -0,0 +1,82 @@ +package digital.util.security; + +import cn.hutool.core.codec.Base64Decoder; +import cn.hutool.core.codec.Base64Encoder; +import cn.hutool.crypto.SecureUtil; +import cn.hutool.crypto.asymmetric.KeyType; +import cn.hutool.crypto.asymmetric.RSA; +import cn.hutool.crypto.asymmetric.Sign; +import cn.hutool.crypto.asymmetric.SignAlgorithm; +import cn.hutool.crypto.symmetric.AES; +import com.alibaba.fastjson.JSONObject; +import digital.util.security.entity.*; +import digital.util.security.entity.*; + +import javax.crypto.SecretKey; +import java.security.KeyPair; + +/** + * @Description: SecurityTools + * @author: smcp + */ +public class SecurityTools { + public static final String ALGORITHM = "AES/ECB/PKCS5Padding"; + + public static SecurityResp valid(SecurityReq req) { + SecurityResp resp=new SecurityResp(); + String pubKey=req.getPubKey(); + String aesKey=req.getAesKey(); + String data=req.getData(); + String signData=req.getSignData(); + RSA rsa=new RSA(null, Base64Decoder.decode(pubKey)); + Sign sign= new Sign(SignAlgorithm.SHA1withRSA,null,pubKey); + + + + byte[] decryptAes = rsa.decrypt(aesKey, KeyType.PublicKey); + //log.info("rsa解密后的秘钥"+ Base64Encoder.encode(decryptAes)); + AES aes = SecureUtil.aes(decryptAes); + + String dencrptValue =aes.decryptStr(data); + //log.info("解密后报文"+dencrptValue); + resp.setData(JSONObject.parseObject(dencrptValue)); + + boolean verify = sign.verify(dencrptValue.getBytes(), Base64Decoder.decode(signData)); + resp.setSuccess(verify); + return resp; + } + + public static SecuritySignResp sign(SecuritySignReq req) { + SecretKey secretKey = SecureUtil.generateKey(ALGORITHM); + byte[] key= secretKey.getEncoded(); + String prikey=req.getPrikey(); + String data=req.getData(); + + AES aes = SecureUtil.aes(key); + aes.getSecretKey().getEncoded(); + String encrptData =aes.encryptBase64(data); + RSA rsa=new RSA(prikey,null); + byte[] encryptAesKey = rsa.encrypt(secretKey.getEncoded(), KeyType.PrivateKey); + //log.info(("rsa加密过的秘钥=="+Base64Encoder.encode(encryptAesKey)); + + Sign sign= new Sign(SignAlgorithm.SHA1withRSA,prikey,null); + byte[] signed = sign.sign(data.getBytes()); + + //log.info(("签名数据===》》"+Base64Encoder.encode(signed)); + + SecuritySignResp resp=new SecuritySignResp(); + resp.setAesKey(Base64Encoder.encode(encryptAesKey)); + resp.setData(encrptData); + resp.setSignData(Base64Encoder.encode(signed)); + return resp; + } + public static MyKeyPair generateKeyPair(){ + KeyPair keyPair= SecureUtil.generateKeyPair(SignAlgorithm.SHA1withRSA.getValue(),2048); + String priKey= Base64Encoder.encode(keyPair.getPrivate().getEncoded()); + String pubkey= Base64Encoder.encode(keyPair.getPublic().getEncoded()); + MyKeyPair resp=new MyKeyPair(); + resp.setPriKey(priKey); + resp.setPubKey(pubkey); + return resp; + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/entity/MyKeyPair.java b/digital-common/digital-util/src/main/java/digital/util/security/entity/MyKeyPair.java new file mode 100644 index 0000000..f274529 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/entity/MyKeyPair.java @@ -0,0 +1,13 @@ +package digital.util.security.entity; + +import lombok.Data; + +/** + * @Description: MyKeyPair + * @author: smcp + */ +@Data +public class MyKeyPair { + private String priKey; + private String pubKey; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityReq.java b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityReq.java new file mode 100644 index 0000000..5520a95 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityReq.java @@ -0,0 +1,15 @@ +package digital.util.security.entity; + +import lombok.Data; + +/** + * @Description: SecurityReq + * @author: smcp + */ +@Data +public class SecurityReq { + private String data; + private String pubKey; + private String signData; + private String aesKey; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityResp.java b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityResp.java new file mode 100644 index 0000000..c4c439e --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecurityResp.java @@ -0,0 +1,14 @@ +package digital.util.security.entity; + +import com.alibaba.fastjson.JSONObject; +import lombok.Data; + +/** + * @Description: SecurityResp + * @author: smcp + */ +@Data +public class SecurityResp { + private Boolean success; + private JSONObject data; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignReq.java b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignReq.java new file mode 100644 index 0000000..69324df --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignReq.java @@ -0,0 +1,13 @@ +package digital.util.security.entity; + +import lombok.Data; + +/** + * @Description: SecuritySignReq + * @author: smcp + */ +@Data +public class SecuritySignReq { + private String data; + private String prikey; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignResp.java b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignResp.java new file mode 100644 index 0000000..dc19991 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/security/entity/SecuritySignResp.java @@ -0,0 +1,14 @@ +package digital.util.security.entity; + +import lombok.Data; + +/** + * @Description: SecuritySignResp + * @author: smcp + */ +@Data +public class SecuritySignResp { + private String data; + private String signData; + private String aesKey; +} diff --git a/digital-common/digital-util/src/main/java/digital/util/superSearch/ObjectParseUtil.java b/digital-common/digital-util/src/main/java/digital/util/superSearch/ObjectParseUtil.java new file mode 100644 index 0000000..5091e9c --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/superSearch/ObjectParseUtil.java @@ -0,0 +1,60 @@ +//package org.jeecg.common.util.superSearch; +// +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +// +///** +// * 判断类型,追加查询规则 +// * +// * @Author Scott +// * @Date 2019年02月14日 +// */ +//public class ObjectParseUtil { +// +// /** +// * +// * @param queryWrapper QueryWrapper +// * @param name 字段名字 +// * @param rule 查询规则 +// * @param value 查询条件值 +// */ +// public static void addCriteria(QueryWrapper queryWrapper, String name, QueryRuleEnum rule, Object value) { +// if (value == null || rule == null) { +// return; +// } +// switch (rule) { +// case GT: +// queryWrapper.gt(name, value); +// break; +// case GE: +// queryWrapper.ge(name, value); +// break; +// case LT: +// queryWrapper.lt(name, value); +// break; +// case LE: +// queryWrapper.le(name, value); +// break; +// case EQ: +// queryWrapper.eq(name, value); +// break; +// case NE: +// queryWrapper.ne(name, value); +// break; +// case IN: +// queryWrapper.in(name, (Object[]) value); +// break; +// case LIKE: +// queryWrapper.like(name, value); +// break; +// case LEFT_LIKE: +// queryWrapper.likeLeft(name, value); +// break; +// case RIGHT_LIKE: +// queryWrapper.likeRight(name, value); +// break; +// default: +// break; +// } +// } +// +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleEnum.java b/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleEnum.java new file mode 100644 index 0000000..b76e1f6 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleEnum.java @@ -0,0 +1,71 @@ +//package org.jeecg.common.util.superSearch; +// +// +// +///** +// * Query 规则 常量 +// * @Author Scott +// * @Date 2019年02月14日 +// */ +//public enum QueryRuleEnum { +// +// /**查询规则 大于*/ +// GT(">","大于"), +// /**查询规则 大于等于*/ +// GE(">=","大于等于"), +// /**查询规则 小于*/ +// LT("<","小于"), +// /**查询规则 小于等于*/ +// LE("<=","小于等于"), +// /**查询规则 等于*/ +// EQ("=","等于"), +// /**查询规则 不等于*/ +// NE("!=","不等于"), +// /**查询规则 包含*/ +// IN("IN","包含"), +// /**查询规则 全模糊*/ +// LIKE("LIKE","全模糊"), +// /**查询规则 左模糊*/ +// LEFT_LIKE("LEFT_LIKE","左模糊"), +// /**查询规则 右模糊*/ +// RIGHT_LIKE("RIGHT_LIKE","右模糊"), +// /**查询规则 自定义SQL片段*/ +// SQL_RULES("EXTEND_SQL","自定义SQL片段"); +// +// private String value; +// +// private String msg; +// +// QueryRuleEnum(String value, String msg){ +// this.value = value; +// this.msg = msg; +// } +// +// public String getValue() { +// return value; +// } +// +// public void setValue(String value) { +// this.value = value; +// } +// +// public String getMsg() { +// return msg; +// } +// +// public void setMsg(String msg) { +// this.msg = msg; +// } +// +// public static QueryRuleEnum getByValue(String value){ +// if(oConvertUtils.isEmpty(value)) { +// return null; +// } +// for(QueryRuleEnum val :values()){ +// if (val.getValue().equals(value)){ +// return val; +// } +// } +// return null; +// } +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleVo.java b/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleVo.java new file mode 100644 index 0000000..f84747c --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/superSearch/QueryRuleVo.java @@ -0,0 +1,15 @@ +//package org.jeecg.common.util.superSearch; +// +//import lombok.Data; +// +///** +// * @Description: QueryRuleVo +// * @author: smcp +// */ +//@Data +//public class QueryRuleVo { +// +// private String field; +// private String rule; +// private String val; +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/BrowserType.java b/digital-common/digital-util/src/main/java/digital/util/util/BrowserType.java new file mode 100644 index 0000000..f5642f9 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/BrowserType.java @@ -0,0 +1,13 @@ +package digital.util.util; + +/** + * + * @Author 张代浩 + * + */ +public enum BrowserType { + /** + * 浏览类型 IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko + */ + IE11,IE10,IE9,IE8,IE7,IE6,Firefox,Safari,Chrome,Opera,Camino,Gecko +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/BrowserUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/BrowserUtils.java new file mode 100644 index 0000000..acdbfe4 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/BrowserUtils.java @@ -0,0 +1,211 @@ +package digital.util.util; + +import javax.servlet.http.HttpServletRequest; +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * + * @Author 张代浩 + * + */ +public class BrowserUtils { + + /** + * 判断是否是IE + * @param request + * @return + */ + public static boolean isIe(HttpServletRequest request) { + return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request + .getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true + : false; + } + + /** + * 获取IE版本 + * + * @param request + * @return + */ + public static Double getIeVersion(HttpServletRequest request) { + Double version = 0.0; + if (getBrowserType(request, IE11)) { + version = 11.0; + } else if (getBrowserType(request, IE10)) { + version = 10.0; + } else if (getBrowserType(request, IE9)) { + version = 9.0; + } else if (getBrowserType(request, IE8)) { + version = 8.0; + } else if (getBrowserType(request, IE7)) { + version = 7.0; + } else if (getBrowserType(request, IE6)) { + version = 6.0; + } + return version; + } + + /** + * 获取浏览器类型 + * + * @param request + * @return + */ + public static BrowserType getBrowserType(HttpServletRequest request) { + BrowserType browserType = null; + if (getBrowserType(request, IE11)) { + browserType = BrowserType.IE11; + } + if (getBrowserType(request, IE10)) { + browserType = BrowserType.IE10; + } + if (getBrowserType(request, IE9)) { + browserType = BrowserType.IE9; + } + if (getBrowserType(request, IE8)) { + browserType = BrowserType.IE8; + } + if (getBrowserType(request, IE7)) { + browserType = BrowserType.IE7; + } + if (getBrowserType(request, IE6)) { + browserType = BrowserType.IE6; + } + if (getBrowserType(request, FIREFOX)) { + browserType = BrowserType.Firefox; + } + if (getBrowserType(request, SAFARI)) { + browserType = BrowserType.Safari; + } + if (getBrowserType(request, CHROME)) { + browserType = BrowserType.Chrome; + } + if (getBrowserType(request, OPERA)) { + browserType = BrowserType.Opera; + } + if (getBrowserType(request, CAMINO)) { + browserType = BrowserType.Camino; + } + return browserType; + } + + private static boolean getBrowserType(HttpServletRequest request, + String brosertype) { + return request.getHeader("USER-AGENT").toLowerCase() + .indexOf(brosertype) > 0 ? true : false; + } + + private final static String IE11 = "rv:11.0"; + private final static String IE10 = "MSIE 10.0"; + private final static String IE9 = "MSIE 9.0"; + private final static String IE8 = "MSIE 8.0"; + private final static String IE7 = "MSIE 7.0"; + private final static String IE6 = "MSIE 6.0"; + private final static String MAXTHON = "Maxthon"; + private final static String QQ = "QQBrowser"; + private final static String GREEN = "GreenBrowser"; + private final static String SE360 = "360SE"; + private final static String FIREFOX = "Firefox"; + private final static String OPERA = "Opera"; + private final static String CHROME = "Chrome"; + private final static String SAFARI = "Safari"; + private final static String OTHER = "其它"; + private final static String CAMINO = "Camino"; + + public static String checkBrowse(HttpServletRequest request) { + String userAgent = request.getHeader("USER-AGENT"); + if (regex(OPERA, userAgent)) { + return OPERA; + } + if (regex(CHROME, userAgent)) { + return CHROME; + } + if (regex(FIREFOX, userAgent)) { + return FIREFOX; + } + if (regex(SAFARI, userAgent)) { + return SAFARI; + } + if (regex(SE360, userAgent)) { + return SE360; + } + if (regex(GREEN, userAgent)) { + return GREEN; + } + if (regex(QQ, userAgent)) { + return QQ; + } + if (regex(MAXTHON, userAgent)) { + return MAXTHON; + } + if (regex(IE11, userAgent)) { + return IE11; + } + if (regex(IE10, userAgent)) { + return IE10; + } + if (regex(IE9, userAgent)) { + return IE9; + } + if (regex(IE8, userAgent)) { + return IE8; + } + if (regex(IE7, userAgent)) { + return IE7; + } + if (regex(IE6, userAgent)) { + return IE6; + } + return OTHER; + } + + public static boolean regex(String regex, String str) { + Pattern p = Pattern.compile(regex, Pattern.MULTILINE); + Matcher m = p.matcher(str); + return m.find(); + } + + + private static Map langMap = new HashMap(); + private final static String ZH = "zh"; + private final static String ZH_CN = "zh-cn"; + + private final static String EN = "en"; + private final static String EN_US = "en"; + + + static + { + langMap.put(ZH, ZH_CN); + langMap.put(EN, EN_US); + } + + public static String getBrowserLanguage(HttpServletRequest request) { + + String browserLang = request.getLocale().getLanguage(); + String browserLangCode = (String)langMap.get(browserLang); + + if(browserLangCode == null) + { + browserLangCode = EN_US; + } + return browserLangCode; + } + + /** 判断请求是否来自电脑端 */ + public static boolean isDesktop(HttpServletRequest request) { + return !isMobile(request); + } + + /** 判断请求是否来自移动端 */ + public static boolean isMobile(HttpServletRequest request) { + String ua = request.getHeader("User-Agent").toLowerCase(); + String type = "(phone|pad|pod|iphone|ipod|ios|ipad|android|mobile|blackberry|iemobile|mqqbrowser|juc|fennec|wosbrowser|browserng|webos|symbian|windows phone)"; + Pattern pattern = Pattern.compile(type); + return pattern.matcher(ua).find(); + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/CommonUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/CommonUtils.java new file mode 100644 index 0000000..8ef4654 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/CommonUtils.java @@ -0,0 +1,349 @@ +package digital.util.util; + +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty; +import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties; +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils; +import lombok.extern.slf4j.Slf4j; +import org.jeecgframework.poi.util.PoiPublicUtil; +import org.springframework.jdbc.datasource.DriverManagerDataSource; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.multipart.MultipartFile; +import digital.base.constant.CommonConstant; +import digital.base.constant.DataBaseConstant; +import digital.base.constant.SymbolConstant; +import digital.util.filter.FileTypeFilter; + +import javax.servlet.http.HttpServletRequest; +import javax.sql.DataSource; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @Description: 通用工具 + * @author: smcp + */ +@Slf4j +public class CommonUtils { + + /** + * 中文正则 + */ + private static Pattern ZHONGWEN_PATTERN = Pattern.compile("[\u4e00-\u9fa5]"); + + /** + * 文件名 正则字符串 + * 文件名支持的字符串:字母数字中文.-_()() 除此之外的字符将被删除 + */ + private static String FILE_NAME_REGEX = "[^A-Za-z\\.\\(\\)\\-()\\_0-9\\u4e00-\\u9fa5]"; + + public static String uploadOnlineImage(byte[] data,String basePath,String bizPath,String uploadType){ + String dbPath = null; + String fileName = "image" + Math.round(Math.random() * 100000000000L); + fileName += "." + PoiPublicUtil.getFileExtendName(data); + try { + if(CommonConstant.UPLOAD_TYPE_LOCAL.equals(uploadType)){ + File file = new File(basePath + File.separator + bizPath + File.separator ); + if (!file.exists()) { + file.mkdirs();// 创建文件根目录 + } + String savePath = file.getPath() + File.separator + fileName; + File savefile = new File(savePath); + FileCopyUtils.copy(data, savefile); + dbPath = bizPath + File.separator + fileName; + }else { + InputStream in = new ByteArrayInputStream(data); + String relativePath = bizPath + "/" + fileName; +// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ +// dbPath = MinioUtil.upload(in,relativePath); +// }else if(CommonConstant.UPLOAD_TYPE_OSS.equals(uploadType)){ +// dbPath = OssBootUtil.upload(in,relativePath); +// } + } + } catch (Exception e) { + e.printStackTrace(); + } + return dbPath; + } + + /** + * 判断文件名是否带盘符,重新处理 + * @param fileName + * @return + */ + public static String getFileName(String fileName){ + //判断是否带有盘符信息 + // Check for Unix-style path + int unixSep = fileName.lastIndexOf('/'); + // Check for Windows-style path + int winSep = fileName.lastIndexOf('\\'); + // Cut off at latest possible point + int pos = (winSep > unixSep ? winSep : unixSep); + if (pos != -1) { + // Any sort of path separator found... + fileName = fileName.substring(pos + 1); + } + //替换上传文件名字的特殊字符 + fileName = fileName.replace("=","").replace(",","").replace("&","") + .replace("#", "").replace("“", "").replace("”", ""); + //替换上传文件名字中的空格 + fileName=fileName.replaceAll("\\s",""); + //update-beign-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常 + fileName = fileName.replaceAll(FILE_NAME_REGEX, ""); + //update-end-author:taoyan date:20220302 for: /issues/3381 online 在线表单 使用文件组件时,上传文件名中含%,下载异常 + return fileName; + } + + /** + * java 判断字符串里是否包含中文字符 + * @param str + * @return + */ + public static boolean ifContainChinese(String str) { + if(str.getBytes().length == str.length()){ + return false; + }else{ + Matcher m = ZHONGWEN_PATTERN.matcher(str); + if (m.find()) { + return true; + } + return false; + } + } + + /** + * 统一全局上传 + * @Return: java.lang.String + */ +// public static String upload(MultipartFile file, String bizPath, String uploadType) { +// String url = ""; +// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ +// url = MinioUtil.upload(file,bizPath); +// }else{ +// url = OssBootUtil.upload(file,bizPath); +// } +// return url; +// } + + /** + * 本地文件上传 + * + * @param mf 文件 + * @param bizPath 自定义路径 + * @return + */ + public static String uploadLocal(MultipartFile mf, String bizPath, String uploadpath) { + try { + //update-begin-author:liusq date:20210809 for: 过滤上传文件类型 + FileTypeFilter.fileTypeFilter(mf); + //update-end-author:liusq date:20210809 for: 过滤上传文件类型 + String fileName = null; + File file = new File(uploadpath + File.separator + bizPath + File.separator ); + if (!file.exists()) { + // 创建文件根目录 + file.mkdirs(); + } + // 获取文件名 + String orgName = mf.getOriginalFilename(); + orgName = CommonUtils.getFileName(orgName); + if(orgName.indexOf(SymbolConstant.SPOT)!=-1){ + fileName = orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")); + }else{ + fileName = orgName+ "_" + System.currentTimeMillis(); + } + String savePath = file.getPath() + File.separator + fileName; + File savefile = new File(savePath); + FileCopyUtils.copy(mf.getBytes(), savefile); + String dbpath = null; + if(oConvertUtils.isNotEmpty(bizPath)){ + dbpath = bizPath + File.separator + fileName; + }else{ + dbpath = fileName; + } + if (dbpath.contains(SymbolConstant.DOUBLE_BACKSLASH)) { + dbpath = dbpath.replace("\\", "/"); + } + return dbpath; + } catch (IOException e) { + log.error(e.getMessage(), e); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return ""; + } + + /** + * 统一全局上传 带桶 + * @Return: java.lang.String + */ +// public static String upload(MultipartFile file, String bizPath, String uploadType, String customBucket) { +// String url = ""; +// if(CommonConstant.UPLOAD_TYPE_MINIO.equals(uploadType)){ +// url = MinioUtil.upload(file,bizPath,customBucket); +// }else{ +// url = OssBootUtil.upload(file,bizPath,customBucket); +// } +// return url; +// } + + /** + * 当前系统数据库类型 + */ + private static String DB_TYPE = ""; + private static DbType dbTypeEnum = null; + + /** + * 全局获取平台数据库类型(作废了) + * + * @return + */ + @Deprecated + public static String getDatabaseType() { + if(oConvertUtils.isNotEmpty(DB_TYPE)){ + return DB_TYPE; + } + DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class); + try { + return getDatabaseTypeByDataSource(dataSource); + } catch (SQLException e) { + //e.printStackTrace(); + log.warn(e.getMessage(),e); + return ""; + } + } + + /** + * 全局获取平台数据库类型(对应mybaisPlus枚举) + * @return + */ + public static DbType getDatabaseTypeEnum() { + if (oConvertUtils.isNotEmpty(dbTypeEnum)) { + return dbTypeEnum; + } + try { + DataSource dataSource = SpringContextUtils.getApplicationContext().getBean(DataSource.class); + dbTypeEnum = JdbcUtils.getDbType(dataSource.getConnection().getMetaData().getURL()); + return dbTypeEnum; + } catch (SQLException e) { + log.warn(e.getMessage(), e); + return null; + } + } + + /** + * 根据数据源key获取DataSourceProperty + * @param sourceKey + * @return + */ + public static DataSourceProperty getDataSourceProperty(String sourceKey){ + DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class); + Map map = prop.getDatasource(); + DataSourceProperty db = (DataSourceProperty)map.get(sourceKey); + return db; + } + + /** + * 根据sourceKey 获取数据源连接 + * @param sourceKey + * @return + * @throws SQLException + */ + public static Connection getDataSourceConnect(String sourceKey) throws SQLException { + if (oConvertUtils.isEmpty(sourceKey)) { + sourceKey = "master"; + } + DynamicDataSourceProperties prop = SpringContextUtils.getApplicationContext().getBean(DynamicDataSourceProperties.class); + Map map = prop.getDatasource(); + DataSourceProperty db = (DataSourceProperty)map.get(sourceKey); + if(db==null){ + return null; + } + DriverManagerDataSource ds = new DriverManagerDataSource (); + ds.setDriverClassName(db.getDriverClassName()); + ds.setUrl(db.getUrl()); + ds.setUsername(db.getUsername()); + ds.setPassword(db.getPassword()); + return ds.getConnection(); + } + + /** + * 获取数据库类型 + * @param dataSource + * @return + * @throws SQLException + */ + private static String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException{ + if("".equals(DB_TYPE)) { + Connection connection = dataSource.getConnection(); + try { + DatabaseMetaData md = connection.getMetaData(); + String dbType = md.getDatabaseProductName().toUpperCase(); + String sqlserver= "SQL SERVER"; + if(dbType.indexOf(DataBaseConstant.DB_TYPE_MYSQL)>=0) { + DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL; + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_ORACLE)>=0 ||dbType.indexOf(DataBaseConstant.DB_TYPE_DM)>=0) { + DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE; + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_SQLSERVER)>=0||dbType.indexOf(sqlserver)>=0) { + DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER; + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_POSTGRESQL)>=0) { + DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL; + }else if(dbType.indexOf(DataBaseConstant.DB_TYPE_MARIADB)>=0) { + DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB; + }else { + log.error("数据库类型:[" + dbType + "]不识别!"); + //throw new JeecgBootException("数据库类型:["+dbType+"]不识别!"); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + }finally { + connection.close(); + } + } + return DB_TYPE; + + } + /** + * 获取服务器地址 + * + * @param request + * @return + */ + public static String getBaseUrl(HttpServletRequest request) { + //1.【兼容】兼容微服务下的 base path------- + String xGatewayBasePath = request.getHeader("X_GATEWAY_BASE_PATH"); + if(oConvertUtils.isNotEmpty(xGatewayBasePath)){ + log.info("x_gateway_base_path = "+ xGatewayBasePath); + return xGatewayBasePath; + } + //2.【兼容】SSL认证之后,request.getScheme()获取不到https的问题 + // https://blog.csdn.net/weixin_34376986/article/details/89767950 + String scheme = request.getHeader("X-Forwarded-Scheme"); + if(oConvertUtils.isEmpty(scheme)){ + scheme = request.getScheme(); + } + + //3.常规操作 + String serverName = request.getServerName(); + int serverPort = request.getServerPort(); + String contextPath = request.getContextPath(); + + //返回 host domain + String baseDomainPath = null; + int length = 80; + if(length == serverPort){ + baseDomainPath = scheme + "://" + serverName + contextPath ; + }else{ + baseDomainPath = scheme + "://" + serverName + ":" + serverPort + contextPath ; + } + log.info("-----Common getBaseUrl----- : " + baseDomainPath); + return baseDomainPath; + } +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/DateUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/DateUtils.java new file mode 100644 index 0000000..5e675db --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/DateUtils.java @@ -0,0 +1,674 @@ +package digital.util.util; + +import org.springframework.util.StringUtils; +import digital.base.constant.SymbolConstant; + +import java.beans.PropertyEditorSupport; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; + +/** + * 类描述:时间操作定义类 + * + * @Author: 张代浩 + * @Date:2012-12-8 12:15:03 + * @Version 1.0 + */ +public class DateUtils extends PropertyEditorSupport { + + public static ThreadLocal date_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd"); + } + }; + public static ThreadLocal yyyyMMdd = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMdd"); + } + }; + public static ThreadLocal date_sdf_wz = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy年MM月dd日"); + } + }; + public static ThreadLocal time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm"); + } + }; + public static ThreadLocal yyyymmddhhmmss = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyyMMddHHmmss"); + } + }; + public static ThreadLocal short_time_sdf = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("HH:mm"); + } + }; + public static ThreadLocal datetimeFormat = new ThreadLocal() { + @Override + protected SimpleDateFormat initialValue() { + return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + } + }; + + /** + * 以毫秒表示的时间 + */ + private static final long DAY_IN_MILLIS = 24 * 3600 * 1000; + private static final long HOUR_IN_MILLIS = 3600 * 1000; + private static final long MINUTE_IN_MILLIS = 60 * 1000; + private static final long SECOND_IN_MILLIS = 1000; + + /** + * 指定模式的时间格式 + * @param pattern + * @return + */ + private static SimpleDateFormat getSdFormat(String pattern) { + return new SimpleDateFormat(pattern); + } + + /** + * 当前日历,这里用中国时间表示 + * + * @return 以当地时区表示的系统当前日历 + */ + public static Calendar getCalendar() { + return Calendar.getInstance(); + } + + /** + * 指定毫秒数表示的日历 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日历 + */ + public static Calendar getCalendar(long millis) { + Calendar cal = Calendar.getInstance(); + // --------------------cal.setTimeInMillis(millis); + cal.setTime(new Date(millis)); + return cal; + } + + // //////////////////////////////////////////////////////////////////////////// + // getDate + // 各种方式获取的Date + // //////////////////////////////////////////////////////////////////////////// + + /** + * 当前日期 + * + * @return 系统当前时间 + */ + public static Date getDate() { + return new Date(); + } + + /** + * 指定毫秒数表示的日期 + * + * @param millis 毫秒数 + * @return 指定毫秒数表示的日期 + */ + public static Date getDate(long millis) { + return new Date(millis); + } + + /** + * 时间戳转换为字符串 + * + * @param time + * @return + */ + public static String timestamptoStr(Timestamp time) { + Date date = null; + if (null != time) { + date = new Date(time.getTime()); + } + return date2Str(date_sdf.get()); + } + + /** + * 字符串转换时间戳 + * + * @param str + * @return + */ + public static Timestamp str2Timestamp(String str) { + Date date = str2Date(str, date_sdf.get()); + return new Timestamp(date.getTime()); + } + + /** + * 字符串转换成日期 + * + * @param str + * @param sdf + * @return + */ + public static Date str2Date(String str, SimpleDateFormat sdf) { + if (null == str || "".equals(str)) { + return null; + } + Date date = null; + try { + date = sdf.parse(str); + return date; + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 日期转换为字符串 + * + * @param dateSdf 日期格式 + * @return 字符串 + */ + public static String date2Str(SimpleDateFormat dateSdf) { + synchronized (dateSdf) { + Date date = getDate(); + if (null == date) { + return null; + } + return dateSdf.format(date); + } + } + + /** + * 格式化时间 + * + * @param date + * @param format + * @return + */ + public static String dateformat(String date, String format) { + SimpleDateFormat sformat = new SimpleDateFormat(format); + Date nowDate = null; + try { + nowDate = sformat.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return sformat.format(nowDate); + } + + /** + * 日期转换为字符串 + * + * @param date 日期 + * @param dateSdf 日期格式 + * @return 字符串 + */ + public static String date2Str(Date date, SimpleDateFormat dateSdf) { + synchronized (dateSdf) { + if (null == date) { + return null; + } + return dateSdf.format(date); + } + } + + /** + * 日期转换为字符串 + * + * @param format 日期格式 + * @return 字符串 + */ + public static String getDate(String format) { + Date date = new Date(); + if (null == date) { + return null; + } + SimpleDateFormat sdf = new SimpleDateFormat(format); + return sdf.format(date); + } + + /** + * 指定毫秒数的时间戳 + * + * @param millis 毫秒数 + * @return 指定毫秒数的时间戳 + */ + public static Timestamp getTimestamp(long millis) { + return new Timestamp(millis); + } + + /** + * 以字符形式表示的时间戳 + * + * @param time 毫秒数 + * @return 以字符形式表示的时间戳 + */ + public static Timestamp getTimestamp(String time) { + return new Timestamp(Long.parseLong(time)); + } + + /** + * 系统当前的时间戳 + * + * @return 系统当前的时间戳 + */ + public static Timestamp getTimestamp() { + return new Timestamp(System.currentTimeMillis()); + } + + /** + * 当前时间,格式 yyyy-MM-dd HH:mm:ss + * + * @return 当前时间的标准形式字符串 + */ + public static String now() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 指定日期的时间戳 + * + * @param date 指定日期 + * @return 指定日期的时间戳 + */ + public static Timestamp getTimestamp(Date date) { + return new Timestamp(date.getTime()); + } + + /** + * 指定日历的时间戳 + * + * @param cal 指定日历 + * @return 指定日历的时间戳 + */ + public static Timestamp getCalendarTimestamp(Calendar cal) { + // ---------------------return new Timestamp(cal.getTimeInMillis()); + return new Timestamp(cal.getTime().getTime()); + } + + public static Timestamp gettimestamp() { + Date dt = new Date(); + DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + String nowTime = df.format(dt); + java.sql.Timestamp buydate = java.sql.Timestamp.valueOf(nowTime); + return buydate; + } + + // //////////////////////////////////////////////////////////////////////////// + // getMillis + // 各种方式获取的Millis + // //////////////////////////////////////////////////////////////////////////// + + /** + * 系统时间的毫秒数 + * + * @return 系统时间的毫秒数 + */ + public static long getMillis() { + return System.currentTimeMillis(); + } + + /** + * 指定日历的毫秒数 + * + * @param cal 指定日历 + * @return 指定日历的毫秒数 + */ + public static long getMillis(Calendar cal) { + // --------------------return cal.getTimeInMillis(); + return cal.getTime().getTime(); + } + + /** + * 指定日期的毫秒数 + * + * @param date 指定日期 + * @return 指定日期的毫秒数 + */ + public static long getMillis(Date date) { + return date.getTime(); + } + + /** + * 指定时间戳的毫秒数 + * + * @param ts 指定时间戳 + * @return 指定时间戳的毫秒数 + */ + public static long getMillis(Timestamp ts) { + return ts.getTime(); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatDate + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 + * + * @return 默认日期按“年-月-日“格式显示 + */ + public static String formatDate() { + return date_sdf.get().format(getCalendar().getTime()); + } + + /** + * 默认方式表示的系统当前日期,具体格式:yyyy-MM-dd HH:mm:ss + * + * @return 默认日期按“yyyy-MM-dd HH:mm:ss“格式显示 + */ + public static String formatDateTime() { + return datetimeFormat.get().format(getCalendar().getTime()); + } + + /** + * 获取时间字符串 + */ + public static String getDataString(SimpleDateFormat formatstr) { + synchronized (formatstr) { + return formatstr.format(getCalendar().getTime()); + } + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Calendar cal) { + return date_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日“格式显示 + */ + public static String formatDate(Date date) { + return date_sdf.get().format(date); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日“格式显示 + */ + public static String formatDate(long millis) { + return date_sdf.get().format(new Date(millis)); + } + + /** + * 默认日期按指定格式显示 + * + * @param pattern 指定的格式 + * @return 默认日期按指定格式显示 + */ + public static String formatDate(String pattern) { + return getSdFormat(pattern).format(getCalendar().getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param cal 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Calendar cal, String pattern) { + return getSdFormat(pattern).format(cal.getTime()); + } + + /** + * 指定日期按指定格式显示 + * + * @param date 指定的日期 + * @param pattern 指定的格式 + * @return 指定日期按指定格式显示 + */ + public static String formatDate(Date date, String pattern) { + return getSdFormat(pattern).format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:年-月-日 时:分 + * + * @return 默认日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime() { + return time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:年-月-日 时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(long millis) { + return time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Calendar cal) { + return time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:年-月-日 时:分 + * + * @param date 指定的日期 + * @return 指定日期按“年-月-日 时:分“格式显示 + */ + public static String formatTime(Date date) { + return time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // formatShortTime + // 将日期按照一定的格式转化为字符串 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 默认方式表示的系统当前日期,具体格式:时:分 + * + * @return 默认日期按“时:分“格式显示 + */ + public static String formatShortTime() { + return short_time_sdf.get().format(getCalendar().getTime()); + } + + /** + * 指定毫秒数表示日期的默认显示,具体格式:时:分 + * + * @param millis 指定的毫秒数 + * @return 指定毫秒数表示日期按“时:分“格式显示 + */ + public static String formatShortTime(long millis) { + return short_time_sdf.get().format(new Date(millis)); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param cal 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Calendar cal) { + return short_time_sdf.get().format(cal.getTime()); + } + + /** + * 指定日期的默认显示,具体格式:时:分 + * + * @param date 指定的日期 + * @return 指定日期按“时:分“格式显示 + */ + public static String formatShortTime(Date date) { + return short_time_sdf.get().format(date); + } + + // //////////////////////////////////////////////////////////////////////////// + // parseDate + // parseCalendar + // parseTimestamp + // 将字符串按照一定的格式转化为日期或时间 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Date parseDate(String src, String pattern) throws ParseException { + return getSdFormat(pattern).parse(src); + + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的日期 + * @throws ParseException + */ + public static Calendar parseCalendar(String src, String pattern) throws ParseException { + + Date date = parseDate(src, pattern); + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + return cal; + } + + public static String formatAddDate(String src, String pattern, int amount) throws ParseException { + Calendar cal; + cal = parseCalendar(src, pattern); + cal.add(Calendar.DATE, amount); + return formatDate(cal); + } + + /** + * 根据指定的格式将字符串转换成Date 如输入:2003-11-19 11:20:20将按照这个转成时间 + * + * @param src 将要转换的原始字符窜 + * @param pattern 转换的匹配格式 + * @return 如果转换成功则返回转换后的时间戳 + * @throws ParseException + */ + public static Timestamp parseTimestamp(String src, String pattern) throws ParseException { + Date date = parseDate(src, pattern); + return new Timestamp(date.getTime()); + } + + // //////////////////////////////////////////////////////////////////////////// + // dateDiff + // 计算两个日期之间的差值 + // //////////////////////////////////////////////////////////////////////////// + + /** + * 计算两个时间之间的差值,根据标志的不同而不同 + * + * @param flag 计算标志,表示按照年/月/日/时/分/秒等计算 + * @param calSrc 减数 + * @param calDes 被减数 + * @return 两个日期之间的差值 + */ + public static int dateDiff(char flag, Calendar calSrc, Calendar calDes) { + + long millisDiff = getMillis(calSrc) - getMillis(calDes); + char year = 'y'; + char day = 'd'; + char hour = 'h'; + char minute = 'm'; + char second = 's'; + + if (flag == year) { + return (calSrc.get(Calendar.YEAR) - calDes.get(Calendar.YEAR)); + } + + if (flag == day) { + return (int) (millisDiff / DAY_IN_MILLIS); + } + + if (flag == hour) { + return (int) (millisDiff / HOUR_IN_MILLIS); + } + + if (flag == minute) { + return (int) (millisDiff / MINUTE_IN_MILLIS); + } + + if (flag == second) { + return (int) (millisDiff / SECOND_IN_MILLIS); + } + + return 0; + } + + public static Long getCurrentTimestamp() { + return Long.valueOf(DateUtils.yyyymmddhhmmss.get().format(new Date())); + } + + /** + * String类型 转换为Date, 如果参数长度为10 转换格式”yyyy-MM-dd“ 如果参数长度为19 转换格式”yyyy-MM-dd + * HH:mm:ss“ * @param text String类型的时间值 + */ + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (StringUtils.hasText(text)) { + try { + int length10 = 10; + int length19 = 19; + if (text.indexOf(SymbolConstant.COLON) == -1 && text.length() == length10) { + setValue(DateUtils.date_sdf.get().parse(text)); + } else if (text.indexOf(SymbolConstant.COLON) > 0 && text.length() == length19) { + setValue(DateUtils.datetimeFormat.get().parse(text)); + } else { + throw new IllegalArgumentException("Could not parse date, date format is error "); + } + } catch (ParseException ex) { + IllegalArgumentException iae = new IllegalArgumentException("Could not parse date: " + ex.getMessage()); + iae.initCause(ex); + throw iae; + } + } else { + setValue(null); + } + } + + public static int getYear() { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(getDate()); + return calendar.get(Calendar.YEAR); + } + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/DigitalPersonUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/DigitalPersonUtils.java new file mode 100644 index 0000000..089ee49 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/DigitalPersonUtils.java @@ -0,0 +1,34 @@ +package digital.util.util; + +import cn.hutool.crypto.SecureUtil; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; + +import java.text.SimpleDateFormat; +import java.util.Date; + + +@Slf4j +@Data +public class DigitalPersonUtils { + + @Value("${digital.secret}") + private String secret; + @Value("${digital.reqFrom}") + private String reqFrom; + @Value("${digital.appId}") + private String appId; + + public String authorization() { + String secrets = this.secret + getCurrentTimestamp(); + String authorization = SecureUtil.md5(secret); + return authorization; + } + + private static String getCurrentTimestamp() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + return sdf.format(new Date()); + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/DySmsEnum.java b/digital-common/digital-util/src/main/java/digital/util/util/DySmsEnum.java new file mode 100644 index 0000000..ed7661c --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/DySmsEnum.java @@ -0,0 +1,87 @@ +package digital.util.util; + +import org.apache.commons.lang3.StringUtils; + +/** + * @Description: 短信枚举类 + * @author: smcp + */ +public enum DySmsEnum { + + /** + * 登录短信模板编码 + */ + LOGIN_TEMPLATE_CODE("SMS_246725484", "数字力场", "code"), + /** + * 忘记密码短信模板编码 + */ + FORGET_PASSWORD_TEMPLATE_CODE("SMS_175435174", "JEECG", "code"), + /** + * 注册账号短信模板编码 + */ + REGISTER_TEMPLATE_CODE("SMS_175430166", "JEECG", "code"), + /** + * 会议通知 + */ + MEET_NOTICE_TEMPLATE_CODE("SMS_201480469", "H5活动之家", "username,title,minute,time"), + /** + * 我的计划通知 + */ + PLAN_NOTICE_TEMPLATE_CODE("SMS_201470515", "H5活动之家", "username,title,time"); + + /** + * 短信模板编码 + */ + private String templateCode; + /** + * 签名 + */ + private String signName; + /** + * 短信模板必需的数据名称,多个key以逗号分隔,此处配置作为校验 + */ + private String keys; + + private DySmsEnum(String templateCode,String signName,String keys) { + this.templateCode = templateCode; + this.signName = signName; + this.keys = keys; + } + + public String getTemplateCode() { + return templateCode; + } + + public void setTemplateCode(String templateCode) { + this.templateCode = templateCode; + } + + public String getSignName() { + return signName; + } + + public void setSignName(String signName) { + this.signName = signName; + } + + public String getKeys() { + return keys; + } + + public void setKeys(String keys) { + this.keys = keys; + } + + public static DySmsEnum toEnum(String templateCode) { + if(StringUtils.isEmpty(templateCode)){ + return null; + } + for(DySmsEnum item : DySmsEnum.values()) { + if(item.getTemplateCode().equals(templateCode)) { + return item; + } + } + return null; + } +} + diff --git a/digital-common/digital-util/src/main/java/digital/util/util/DySmsHelper.java b/digital-common/digital-util/src/main/java/digital/util/util/DySmsHelper.java new file mode 100644 index 0000000..3a1b5c2 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/DySmsHelper.java @@ -0,0 +1,126 @@ +package digital.util.util; + +import com.alibaba.fastjson.JSONObject; +import com.aliyuncs.DefaultAcsClient; +import com.aliyuncs.IAcsClient; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest; +import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse; +import com.aliyuncs.exceptions.ClientException; +import com.aliyuncs.profile.DefaultProfile; +import com.aliyuncs.profile.IClientProfile; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created on 17/6/7. + * 短信API产品的DEMO程序,工程中包含了一个SmsDemo类,直接通过 + * 执行main函数即可体验短信产品API功能(只需要将AK替换成开通了云通信-短信产品功能的AK即可) + * 工程依赖了2个jar包(存放在工程的libs目录下) + * 1:aliyun-java-sdk-core.jar + * 2:aliyun-java-sdk-dysmsapi.jar + *

+ * 备注:Demo工程编码采用UTF-8 + * 国际短信发送请勿参照此DEMO + * + * @author: smcp + */ +public class DySmsHelper { + + /** + * 产品名称:云通信短信API产品,开发者无需替换 + */ + static final String PRODUCT = "Dysmsapi"; + /** + * 产品域名,开发者无需替换 + */ + static final String DOMAIN = "dysmsapi.aliyuncs.com"; + private final static Logger logger = LoggerFactory.getLogger(DySmsHelper.class); + /** + * TODO 此处需要替换成开发者自己的AK(在阿里云访问控制台寻找) + */ + static String accessKeyId = "LTAI5t6x568R1E6hVvgdr1B9"; + static String accessKeySecret = "F8uPuRJI5Tq0ICKyuhRBNF6MxOlXo0"; + + public static String getAccessKeyId() { + return accessKeyId; + } + + public static void setAccessKeyId(String accessKeyId) { + DySmsHelper.accessKeyId = accessKeyId; + } + + public static String getAccessKeySecret() { + return accessKeySecret; + } + + public static void setAccessKeySecret(String accessKeySecret) { + DySmsHelper.accessKeySecret = accessKeySecret; + } + + public static boolean sendSms(String phone, JSONObject templateParamJson, DySmsEnum dySmsEnum) throws ClientException { + //可自助调整超时时间 + System.setProperty("sun.net.client.defaultConnectTimeout", "10000"); + System.setProperty("sun.net.client.defaultReadTimeout", "10000"); + + //update-begin-author:taoyan date:20200811 for:配置类数据获取 +// StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class); +// setAccessKeyId(staticConfig.getAccessKeyId()); +// setAccessKeySecret(staticConfig.getAccessKeySecret()); + //update-end-author:taoyan date:20200811 for:配置类数据获取 + + //初始化acsClient,暂不支持region化 + IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret); + DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", PRODUCT, DOMAIN); + IAcsClient acsClient = new DefaultAcsClient(profile); + + //验证json参数 + validateParam(templateParamJson, dySmsEnum); + + //组装请求对象-具体描述见控制台-文档部分内容 + SendSmsRequest request = new SendSmsRequest(); + //必填:待发送手机号 + request.setPhoneNumbers(phone); + //必填:短信签名-可在短信控制台中找到 + request.setSignName(dySmsEnum.getSignName()); + //必填:短信模板-可在短信控制台中找到 + request.setTemplateCode(dySmsEnum.getTemplateCode()); + //可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}"时,此处的值为 + request.setTemplateParam(templateParamJson.toJSONString()); + + //选填-上行短信扩展码(无特殊需求用户请忽略此字段) + //request.setSmsUpExtendCode("90997"); + + //可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者 + //request.setOutId("yourOutId"); + + boolean result = false; + + //hint 此处可能会抛出异常,注意catch + SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request); + logger.info("短信接口返回的数据----------------"); + logger.info("{Code:" + sendSmsResponse.getCode() + ",Message:" + sendSmsResponse.getMessage() + ",RequestId:" + sendSmsResponse.getRequestId() + ",BizId:" + sendSmsResponse.getBizId() + "}"); + String ok = "OK"; + if (ok.equals(sendSmsResponse.getCode())) { + result = true; + } + return result; + + } + + private static void validateParam(JSONObject templateParamJson, DySmsEnum dySmsEnum) { + String keys = dySmsEnum.getKeys(); + String[] keyArr = keys.split(","); + for (String item : keyArr) { + if (!templateParamJson.containsKey(item)) { + throw new RuntimeException("模板缺少参数:" + item); + } + } + } + + +// public static void main(String[] args) throws ClientException, InterruptedException { +// JSONObject obj = new JSONObject(); +// obj.put("code", "1234"); +// sendSms("18610015538", obj, DySmsEnum.LOGIN_TEMPLATE_CODE); +// } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/EmailUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/EmailUtils.java new file mode 100644 index 0000000..ab6fc5b --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/EmailUtils.java @@ -0,0 +1,23 @@ +package digital.util.util; + +/** + * author: smcp + * date:2022-08-15 16:18 + * description: + **/ +public class EmailUtils { + + public static String email(String email) { + if (oConvertUtils.isEmpty(email)) { + return ""; + } + int index = email.indexOf("@"); + if (index <= 1){ + return email; + } + String begin = email.substring(0, 1); + String end = email.substring(index); + String stars = "**"; + return begin + stars + end; + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/FillRuleUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/FillRuleUtil.java new file mode 100644 index 0000000..9eadd1a --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/FillRuleUtil.java @@ -0,0 +1,57 @@ +package digital.util.util; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import digital.base.handler.IFillRuleHandler; + + +/** + * 规则值自动生成工具类 + * + * @author qinfeng + * @举例: 自动生成订单号;自动生成当前日期 + */ +@Slf4j +public class FillRuleUtil { + + /** + * @param ruleCode ruleCode + * @return + */ + @SuppressWarnings("unchecked") + public static Object executeRule(String ruleCode, JSONObject formData) { + if (!StringUtils.isEmpty(ruleCode)) { + try { + // 获取 Service + ServiceImpl impl = (ServiceImpl) SpringContextUtils.getBean("sysFillRuleServiceImpl"); + // 根据 ruleCode 查询出实体 + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("rule_code", ruleCode); + JSONObject entity = JSON.parseObject(JSON.toJSONString(impl.getOne(queryWrapper))); + if (entity == null) { + log.warn("填值规则:" + ruleCode + " 不存在"); + return null; + } + // 获取必要的参数 + String ruleClass = entity.getString("ruleClass"); + JSONObject params = entity.getJSONObject("ruleParams"); + if (params == null) { + params = new JSONObject(); + } + if (formData == null) { + formData = new JSONObject(); + } + // 通过反射执行配置的类里的方法 + IFillRuleHandler ruleHandler = (IFillRuleHandler) Class.forName(ruleClass).newInstance(); + return ruleHandler.execute(params, formData); + } catch (Exception e) { + e.printStackTrace(); + } + } + return null; + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/HTMLUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/HTMLUtils.java new file mode 100644 index 0000000..2a9baf2 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/HTMLUtils.java @@ -0,0 +1,32 @@ +package digital.util.util; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.util.HtmlUtils; + +/** + * HTML 工具类 + * @author: smcp + * @date: 2022/3/30 14:43 + */ +@SuppressWarnings("AlibabaClassNamingShouldBeCamel") +public class HTMLUtils { + + /** + * 获取HTML内的文本,不包含标签 + * + * @param html HTML 代码 + */ + public static String getInnerText(String html) { + if (StringUtils.isNotBlank(html)) { + //去掉 html 的标签 + String content = html.replaceAll("]+>", ""); + // 将多个空格合并成一个空格 + content = content.replaceAll("( )+", " "); + // 反向转义字符 + content = HtmlUtils.htmlUnescape(content); + return content.trim(); + } + return ""; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/ImportExcelUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/ImportExcelUtil.java new file mode 100644 index 0000000..e1e0ce0 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/ImportExcelUtil.java @@ -0,0 +1,97 @@ +package digital.util.util; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import lombok.extern.slf4j.Slf4j; +import digital.base.constant.CommonConstant; +import digital.base.vo.Result; + +import java.io.File; +import java.io.IOException; +import java.util.List; + +/** + * 导出返回信息 + * @author: smcp + */ +@Slf4j +public class ImportExcelUtil { + + public static Result imporReturnRes(int errorLines,int successLines,List errorMessage) throws IOException { + if (errorLines == 0) { + return Result.ok("共" + successLines + "行数据全部导入成功!"); + } else { + JSONObject result = new JSONObject(5); + int totalCount = successLines + errorLines; + result.put("totalCount", totalCount); + result.put("errorCount", errorLines); + result.put("successCount", successLines); + result.put("msg", "总上传行数:" + totalCount + ",已导入行数:" + successLines + ",错误行数:" + errorLines); + String fileUrl = PmsUtil.saveErrorTxtByList(errorMessage, "userImportExcelErrorLog"); + int lastIndex = fileUrl.lastIndexOf(File.separator); + String fileName = fileUrl.substring(lastIndex + 1); + result.put("fileUrl", "/sys/common/static/" + fileUrl); + result.put("fileName", fileName); + Result res = Result.ok(result); + res.setCode(201); + res.setMessage("文件导入成功,但有错误。"); + return res; + } + } + + public static List importDateSave(List list, Class serviceClass, List errorMessage, String errorFlag) { + IService bean =(IService) SpringContextUtils.getBean(serviceClass); + for (int i = 0; i < list.size(); i++) { + try { + boolean save = bean.save(list.get(i)); + if(!save){ + throw new Exception(errorFlag); + } + } catch (Exception e) { + String message = e.getMessage().toLowerCase(); + int lineNumber = i + 1; + // 通过索引名判断出错信息 + if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。"); + } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) { + errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。"); + }else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。"); + }else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。"); + }else { + errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入"); + log.error(e.getMessage(), e); + } + } + } + return errorMessage; + } + + public static List importDateSaveOne(Object obj, Class serviceClass,List errorMessage,int i,String errorFlag) { + IService bean =(IService) SpringContextUtils.getBean(serviceClass); + try { + boolean save = bean.save(obj); + if(!save){ + throw new Exception(errorFlag); + } + } catch (Exception e) { + String message = e.getMessage().toLowerCase(); + int lineNumber = i + 1; + // 通过索引名判断出错信息 + if (message.contains(CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:角色编码已经存在,忽略导入。"); + } else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_JOB_CLASS_NAME)) { + errorMessage.add("第 " + lineNumber + " 行:任务类名已经存在,忽略导入。"); + }else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:职务编码已经存在,忽略导入。"); + }else if (message.contains(CommonConstant.SQL_INDEX_UNIQ_DEPART_ORG_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:部门编码已经存在,忽略导入。"); + }else { + errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入"); + log.error(e.getMessage(), e); + } + } + return errorMessage; + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/IpUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/IpUtils.java new file mode 100644 index 0000000..1eaa0b7 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/IpUtils.java @@ -0,0 +1,61 @@ +package digital.util.util; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import digital.base.constant.CommonConstant; + +import javax.servlet.http.HttpServletRequest; + +/** + * IP地址 + * + * @Author scott + * + * update: 【类名改了大小写】 date: 2022-04-18 + * @email jeecgos@163.com + * @Date 2019年01月14日 + */ +public class IpUtils { + private static Logger logger = LoggerFactory.getLogger(IpUtils.class); + + /** + * 获取IP地址 + * + * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址 + * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址 + */ + public static String getIpAddr(HttpServletRequest request) { + String ip = null; + try { + ip = request.getHeader("x-forwarded-for"); + if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || ip.length() == 0 ||CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_CLIENT_IP"); + } + if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getHeader("HTTP_X_FORWARDED_FOR"); + } + if (StringUtils.isEmpty(ip) || CommonConstant.UNKNOWN.equalsIgnoreCase(ip)) { + ip = request.getRemoteAddr(); + } + } catch (Exception e) { + logger.error("IPUtils ERROR ", e); + } + +// //使用代理,则获取第一个IP地址 +// if(StringUtils.isEmpty(ip) && ip.length() > 15) { +// if(ip.indexOf(",") > 0) { +// ip = ip.substring(0, ip.indexOf(",")); +// } +// } + + return ip; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/JeecgDataAutorUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/JeecgDataAutorUtils.java new file mode 100644 index 0000000..845aacb --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/JeecgDataAutorUtils.java @@ -0,0 +1,106 @@ +package digital.util.util; + +import org.springframework.util.StringUtils; +import digital.base.vo.SysPermissionDataRuleModel; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; + +/** + * @ClassName: JeecgDataAutorUtils + * @Description: 数据权限查询规则容器工具类 + * @Author: 张代浩 + * @Date: 2012-12-15 下午11:27:39 + */ +public class JeecgDataAutorUtils { + + public static final String MENU_DATA_AUTHOR_RULES = "MENU_DATA_AUTHOR_RULES"; + + public static final String MENU_DATA_AUTHOR_RULE_SQL = "MENU_DATA_AUTHOR_RULE_SQL"; + + public static final String SYS_USER_INFO = "SYS_USER_INFO"; + + /** + * 往链接请求里面,传入数据查询条件 + * + * @param request + * @param dataRules + */ + public static synchronized void installDataSearchConditon(HttpServletRequest request, List dataRules) { + @SuppressWarnings("unchecked") + // 1.先从request获取MENU_DATA_AUTHOR_RULES,如果存则获取到LIST + List list = (List) loadDataSearchConditon(); + if (list == null) { + // 2.如果不存在,则new一个list + list = new ArrayList(); + } + for (SysPermissionDataRuleModel tsDataRule : dataRules) { + list.add(tsDataRule); + } + // 3.往list里面增量存指 + request.setAttribute(MENU_DATA_AUTHOR_RULES, list); + } + + /** + * 获取请求对应的数据权限规则 + * + * @return + */ + @SuppressWarnings("unchecked") + public static synchronized List loadDataSearchConditon() { + return (List) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULES); + + } + + /** + * 获取请求对应的数据权限SQL + * + * @return + */ + public static synchronized String loadDataSearchConditonSqlString() { + return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL); + } + + /** + * 往链接请求里面,传入数据查询条件 + * + * @param request + * @param sql + */ + public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) { + String ruleSql = (String) loadDataSearchConditonSqlString(); + if (!StringUtils.hasText(ruleSql)) { + request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL, sql); + } + } + + /** + * 将用户信息存到request + * + * @param request + * @param userinfo + */ + public static synchronized void installUserInfo(HttpServletRequest request, SysUserCacheInfo userinfo) { + request.setAttribute(SYS_USER_INFO, userinfo); + } + + /** + * 将用户信息存到request + * + * @param userinfo + */ + public static synchronized void installUserInfo(SysUserCacheInfo userinfo) { + SpringContextUtils.getHttpServletRequest().setAttribute(SYS_USER_INFO, userinfo); + } + + /** + * 从request获取用户信息 + * + * @return + */ + public static synchronized SysUserCacheInfo loadUserInfo() { + return (SysUserCacheInfo) SpringContextUtils.getHttpServletRequest().getAttribute(SYS_USER_INFO); + + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/JeecgRedisUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/JeecgRedisUtil.java new file mode 100644 index 0000000..305620b --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/JeecgRedisUtil.java @@ -0,0 +1,613 @@ +package digital.util.util; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.RedisCallback; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.ScanOptions; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.TimeUnit; + +/** + * redis 工具类 + * @Author Scott + * + */ +@Component +public class JeecgRedisUtil { + + @Autowired + private RedisTemplate redisTemplate; + + /** + * 指定缓存失效时间 + * + * @param key 键 + * @param time 时间(秒) + * @return + */ + public boolean expire(String key, long time) { + try { + if (time > 0) { + redisTemplate.expire(key, time, TimeUnit.SECONDS); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据key 获取过期时间 + * + * @param key 键 不能为null + * @return 时间(秒) 返回0代表为永久有效 + */ + public long getExpire(String key) { + return redisTemplate.getExpire(key, TimeUnit.SECONDS); + } + + /** + * 判断key是否存在 + * + * @param key 键 + * @return true 存在 false不存在 + */ + public boolean hasKey(String key) { + try { + return redisTemplate.hasKey(key); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除缓存 + * + * @param key 可以传一个值 或多个 + */ + @SuppressWarnings("unchecked") + public void del(String... key) { + if (key != null && key.length > 0) { + if (key.length == 1) { + redisTemplate.delete(key[0]); + } else { + //springboot2.4后用法 + redisTemplate.delete(Arrays.asList(key)); + } + } + } + + // ============================String============================= + /** + * 普通缓存获取 + * + * @param key 键 + * @return 值 + */ + public Object get(String key) { + return key == null ? null : redisTemplate.opsForValue().get(key); + } + + /** + * 普通缓存放入 + * + * @param key 键 + * @param value 值 + * @return true成功 false失败 + */ + public boolean set(String key, Object value) { + try { + redisTemplate.opsForValue().set(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + + } + + /** + * 普通缓存放入并设置时间 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期 + * @return true成功 false 失败 + */ + public boolean set(String key, Object value, long time) { + try { + if (time > 0) { + redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS); + } else { + set(key, value); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 递增 + * + * @param key 键 + * @param by 要增加几(大于0) + * @return + */ + public long incr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递增因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, delta); + } + + /** + * 递减 + * + * @param key 键 + * @param by 要减少几(小于0) + * @return + */ + public long decr(String key, long delta) { + if (delta < 0) { + throw new RuntimeException("递减因子必须大于0"); + } + return redisTemplate.opsForValue().increment(key, -delta); + } + + // ================================Map================================= + /** + * HashGet + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return 值 + */ + public Object hget(String key, String item) { + return redisTemplate.opsForHash().get(key, item); + } + + /** + * 获取hashKey对应的所有键值 + * + * @param key 键 + * @return 对应的多个键值 + */ + public Map hmget(String key) { + return redisTemplate.opsForHash().entries(key); + } + + /** + * HashSet + * + * @param key 键 + * @param map 对应多个键值 + * @return true 成功 false 失败 + */ + public boolean hmset(String key, Map map) { + try { + redisTemplate.opsForHash().putAll(key, map); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * HashSet 并设置时间 + * + * @param key 键 + * @param map 对应多个键值 + * @param time 时间(秒) + * @return true成功 false失败 + */ + public boolean hmset(String key, Map map, long time) { + try { + redisTemplate.opsForHash().putAll(key, map); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value) { + try { + redisTemplate.opsForHash().put(key, item, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 向一张hash表中放入数据,如果不存在将创建 + * + * @param key 键 + * @param item 项 + * @param value 值 + * @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间 + * @return true 成功 false失败 + */ + public boolean hset(String key, String item, Object value, long time) { + try { + redisTemplate.opsForHash().put(key, item, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 删除hash表中的值 + * + * @param key 键 不能为null + * @param item 项 可以使多个 不能为null + */ + public void hdel(String key, Object... item) { + redisTemplate.opsForHash().delete(key, item); + } + + /** + * 判断hash表中是否有该项的值 + * + * @param key 键 不能为null + * @param item 项 不能为null + * @return true 存在 false不存在 + */ + public boolean hHasKey(String key, String item) { + return redisTemplate.opsForHash().hasKey(key, item); + } + + /** + * hash递增 如果不存在,就会创建一个 并把新增后的值返回 + * + * @param key 键 + * @param item 项 + * @param by 要增加几(大于0) + * @return + */ + public double hincr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, by); + } + + /** + * hash递减 + * + * @param key 键 + * @param item 项 + * @param by 要减少记(小于0) + * @return + */ + public double hdecr(String key, String item, double by) { + return redisTemplate.opsForHash().increment(key, item, -by); + } + + // ============================set============================= + /** + * 根据key获取Set中的所有值 + * + * @param key 键 + * @return + */ + public Set sGet(String key) { + try { + return redisTemplate.opsForSet().members(key); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 根据value从一个set中查询,是否存在 + * + * @param key 键 + * @param value 值 + * @return true 存在 false不存在 + */ + public boolean sHasKey(String key, Object value) { + try { + return redisTemplate.opsForSet().isMember(key, value); + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将数据放入set缓存 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSet(String key, Object... values) { + try { + return redisTemplate.opsForSet().add(key, values); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 将set数据放入缓存 + * + * @param key 键 + * @param time 时间(秒) + * @param values 值 可以是多个 + * @return 成功个数 + */ + public long sSetAndTime(String key, long time, Object... values) { + try { + Long count = redisTemplate.opsForSet().add(key, values); + if (time > 0) { + expire(key, time); + } + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取set缓存的长度 + * + * @param key 键 + * @return + */ + public long sGetSetSize(String key) { + try { + return redisTemplate.opsForSet().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 移除值为value的 + * + * @param key 键 + * @param values 值 可以是多个 + * @return 移除的个数 + */ + public long setRemove(String key, Object... values) { + try { + Long count = redisTemplate.opsForSet().remove(key, values); + return count; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + // ===============================list================================= + + /** + * 获取list缓存的内容 + * + * @param key 键 + * @param start 开始 + * @param end 结束 0 到 -1代表所有值 + * @return + */ + public List lGet(String key, long start, long end) { + try { + return redisTemplate.opsForList().range(key, start, end); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取list缓存的长度 + * + * @param key 键 + * @return + */ + public long lGetListSize(String key) { + try { + return redisTemplate.opsForList().size(key); + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 通过索引 获取list中的值 + * + * @param key 键 + * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 + * @return + */ + public Object lGetIndex(String key, long index) { + try { + return redisTemplate.opsForList().index(key, index); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value) { + try { + redisTemplate.opsForList().rightPush(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, Object value, long time) { + try { + redisTemplate.opsForList().rightPush(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 将list放入缓存 + * + * @param key 键 + * @param value 值 + * @param time 时间(秒) + * @return + */ + public boolean lSet(String key, List value, long time) { + try { + redisTemplate.opsForList().rightPushAll(key, value); + if (time > 0) { + expire(key, time); + } + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 根据索引修改list中的某条数据 + * + * @param key 键 + * @param index 索引 + * @param value 值 + * @return + */ + public boolean lUpdateIndex(String key, long index, Object value) { + try { + redisTemplate.opsForList().set(key, index, value); + return true; + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + /** + * 移除N个值为value + * + * @param key 键 + * @param count 移除多少个 + * @param value 值 + * @return 移除的个数 + */ + public long lRemove(String key, long count, Object value) { + try { + Long remove = redisTemplate.opsForList().remove(key, count, value); + return remove; + } catch (Exception e) { + e.printStackTrace(); + return 0; + } + } + + /** + * 获取指定前缀的一系列key + * 使用scan命令代替keys, Redis是单线程处理,keys命令在KEY数量较多时, + * 操作效率极低【时间复杂度为O(N)】,该命令一旦执行会严重阻塞线上其它命令的正常请求 + * @param keyPrefix + * @return + */ + private Set keys(String keyPrefix) { + String realKey = keyPrefix + "*"; + + try { + return redisTemplate.execute((RedisCallback>) connection -> { + Set binaryKeys = new HashSet<>(); + //springboot2.4后用法 + Cursor cursor = connection.scan(ScanOptions.scanOptions().match(realKey).count(Integer.MAX_VALUE).build()); + while (cursor.hasNext()) { + binaryKeys.add(new String(cursor.next())); + } + + return binaryKeys; + }); + } catch (Throwable e) { + e.printStackTrace(); + } + + return null; + } + + /** + * 删除指定前缀的一系列key + * @param keyPrefix + */ + public void removeAll(String keyPrefix) { + try { + Set keys = keys(keyPrefix); + redisTemplate.delete(keys); + } catch (Throwable e) { + e.printStackTrace(); + } + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/JwtUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/JwtUtil.java new file mode 100644 index 0000000..4c9a749 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/JwtUtil.java @@ -0,0 +1,261 @@ +package digital.util.util; + +import com.auth0.jwt.JWT; +import com.auth0.jwt.JWTVerifier; +import com.auth0.jwt.algorithms.Algorithm; +import com.auth0.jwt.exceptions.JWTDecodeException; +import com.auth0.jwt.interfaces.DecodedJWT; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Joiner; +import org.apache.shiro.SecurityUtils; +import digital.base.constant.CommonConstant; +import digital.base.constant.DataBaseConstant; +import digital.base.constant.SymbolConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.util.exception.JeecgBootException; + +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Date; + + +/** + * @Author Scott + * @Date 2018-07-12 14:23 + * @Desc JWT工具类 + **/ +public class JwtUtil { + + /** + * Token有效期为7天(Token在reids中缓存时间为两倍) + */ + public static final long EXPIRE_TIME = (7 * 12) * 60 * 60 * 1000; + static final String WELL_NUMBER = SymbolConstant.WELL_NUMBER + SymbolConstant.LEFT_CURLY_BRACKET; + + /** + * @param response + * @param code + * @param errorMsg + */ + public static void responseError(ServletResponse response, Integer code, String errorMsg) { + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + // issues/I4YH95浏览器显示乱码问题 + httpServletResponse.setHeader("Content-type", "text/html;charset=UTF-8"); + Result jsonResult = new Result(code, errorMsg); + OutputStream os = null; + try { + os = httpServletResponse.getOutputStream(); + httpServletResponse.setCharacterEncoding("UTF-8"); + httpServletResponse.setStatus(401); + os.write(new ObjectMapper().writeValueAsString(jsonResult).getBytes("UTF-8")); + os.flush(); + os.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * 校验token是否正确 + * + * @param token 密钥 + * @param secret 用户的密码 + * @return 是否正确 + */ + public static boolean verify(String token, String username, String secret) { + try { + // 根据密码生成JWT效验器 + Algorithm algorithm = Algorithm.HMAC256(secret); + JWTVerifier verifier = JWT.require(algorithm).withClaim("username", username).build(); + // 效验TOKEN + DecodedJWT jwt = verifier.verify(token); + return true; + } catch (Exception exception) { + return false; + } + } + + /** + * 获得token中的信息无需secret解密也能获得 + * + * @return token中包含的用户名 + */ + public static String getUsername(String token) { + try { + DecodedJWT jwt = JWT.decode(token); + return jwt.getClaim("username").asString(); + } catch (JWTDecodeException e) { + return null; + } + } + + /** + * 生成签名,5min后过期 + * + * @param username 用户名 + * @param secret 用户的密码 + * @return 加密的token + */ + public static String sign(String username, String secret) { + Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); + Algorithm algorithm = Algorithm.HMAC256(secret); + // 附带username信息 + return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm); + } + + public static String getToken(String username, String secret) { + Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME); + Algorithm algorithm = Algorithm.HMAC256(secret); + // 附带username信息 + return JWT.create().withClaim("username", username).withExpiresAt(date).sign(algorithm); + } + + /** + * 根据request中的token获取用户账号 + * + * @param request + * @return + * @throws JeecgBootException + */ + public static String getUserNameByToken(HttpServletRequest request) throws JeecgBootException { + String accessToken = request.getHeader("X-Access-Token"); + String username = getUsername(accessToken); + if (oConvertUtils.isEmpty(username)) { + throw new JeecgBootException("未获取到用户"); + } + return username; + } + + /** + * 从session中获取变量 + * + * @param key + * @return + */ + public static String getSessionData(String key) { + //${myVar}% + //得到${} 后面的值 + String moshi = ""; + String wellNumber = WELL_NUMBER; + + if (key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET) != -1) { + moshi = key.substring(key.indexOf("}") + 1); + } + String returnValue = null; + if (key.contains(wellNumber)) { + key = key.substring(2, key.indexOf("}")); + } + if (oConvertUtils.isNotEmpty(key)) { + HttpSession session = SpringContextUtils.getHttpServletRequest().getSession(); + returnValue = (String) session.getAttribute(key); + } + //结果加上${} 后面的值 + if (returnValue != null) { + returnValue = returnValue + moshi; + } + return returnValue; + } + + /** + * 从当前用户中获取变量 + * + * @param key + * @param user + * @return + */ + public static String getUserSystemData(String key, SysUserCacheInfo user) { + if (user == null) { + user = JeecgDataAutorUtils.loadUserInfo(); + } + //#{sys_user_code}% + + // 获取登录用户信息 + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + String moshi = ""; + String wellNumber = WELL_NUMBER; + if (key.indexOf(SymbolConstant.RIGHT_CURLY_BRACKET) != -1) { + moshi = key.substring(key.indexOf("}") + 1); + } + String returnValue = null; + //针对特殊标示处理#{sysOrgCode},判断替换 + if (key.contains(wellNumber)) { + key = key.substring(2, key.indexOf("}")); + } else { + key = key; + } + //替换为系统登录用户帐号 + if (key.equals(DataBaseConstant.SYS_USER_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_USER_CODE_TABLE)) { + if (user == null) { + returnValue = sysUser.getUsername(); + } else { + returnValue = user.getSysUserCode(); + } + } + //替换为系统登录用户真实名字 + else if (key.equals(DataBaseConstant.SYS_USER_NAME) || key.toLowerCase().equals(DataBaseConstant.SYS_USER_NAME_TABLE)) { + if (user == null) { + returnValue = sysUser.getRealname(); + } else { + returnValue = user.getSysUserName(); + } + } + + //替换为系统用户登录所使用的机构编码 + else if (key.equals(DataBaseConstant.SYS_ORG_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_ORG_CODE_TABLE)) { +// if (user == null) { +// returnValue = sysUser.getOrgCode(); +// } else { +// returnValue = user.getSysOrgCode(); +// } + } + //替换为系统用户所拥有的所有机构编码 + else if (key.equals(DataBaseConstant.SYS_MULTI_ORG_CODE) || key.toLowerCase().equals(DataBaseConstant.SYS_MULTI_ORG_CODE_TABLE)) { + if (user == null) { + //TODO 暂时使用用户登录部门,存在逻辑缺陷,不是用户所拥有的部门 +// returnValue = sysUser.getOrgCode(); + } else { + if (user.isOneDepart()) { + returnValue = user.getSysMultiOrgCode().get(0); + } else { + returnValue = Joiner.on(",").join(user.getSysMultiOrgCode()); + } + } + } + //替换为当前系统时间(年月日) + else if (key.equals(DataBaseConstant.SYS_DATE) || key.toLowerCase().equals(DataBaseConstant.SYS_DATE_TABLE)) { + returnValue = DateUtils.formatDate(); + } + //替换为当前系统时间(年月日时分秒) + else if (key.equals(DataBaseConstant.SYS_TIME) || key.toLowerCase().equals(DataBaseConstant.SYS_TIME_TABLE)) { + returnValue = DateUtils.now(); + } + //流程状态默认值(默认未发起) + else if (key.equals(DataBaseConstant.BPM_STATUS) || key.toLowerCase().equals(DataBaseConstant.BPM_STATUS_TABLE)) { + returnValue = "1"; + } + //update-begin-author:taoyan date:20210330 for:多租户ID作为系统变量 + else if (key.equals(DataBaseConstant.TENANT_ID) || key.toLowerCase().equals(DataBaseConstant.TENANT_ID_TABLE)) { +// returnValue = sysUser.getRelTenantIds(); + boolean flag = returnValue != null && returnValue.indexOf(SymbolConstant.COMMA) > 0; + if (oConvertUtils.isEmpty(returnValue) || flag) { + returnValue = SpringContextUtils.getHttpServletRequest().getHeader(CommonConstant.TENANT_ID); + } + } + //update-end-author:taoyan date:20210330 for:多租户ID作为系统变量 + if (returnValue != null) { + returnValue = returnValue + moshi; + } + return returnValue; + } + +// public static void main(String[] args) { +// String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1NjUzMzY1MTMsInVzZXJuYW1lIjoiYWRtaW4ifQ.xjhud_tWCNYBOg_aRlMgOdlZoWFFKB_givNElHNw3X0"; +// System.out.println(JwtUtil.getUsername(token)); +// } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/ListToStringConverter.java b/digital-common/digital-util/src/main/java/digital/util/util/ListToStringConverter.java new file mode 100644 index 0000000..d9dfc37 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/ListToStringConverter.java @@ -0,0 +1,16 @@ +package digital.util.util; + +import java.util.List; + +public class ListToStringConverter { + public static String convert(List list) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < list.size(); i++) { + sb.append(list.get(i)); + if (i < list.size() - 1) { + sb.append("-"); + } + } + return sb.toString(); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/Md5Util.java b/digital-common/digital-util/src/main/java/digital/util/util/Md5Util.java new file mode 100644 index 0000000..560f2bd --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/Md5Util.java @@ -0,0 +1,49 @@ +package digital.util.util; + +import java.security.MessageDigest; + +/** + * @Description: 加密工具 + * + * update: 【类名改了大小写】 date: 2022-04-18 + * @author: smcp + */ +public class Md5Util { + + private static final String[] HEXDIGITS = { "0", "1", "2", "3", "4", "5", + "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" }; + + public 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) { + } + return resultString; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/MinioUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/MinioUtil.java new file mode 100644 index 0000000..91fd6dc --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/MinioUtil.java @@ -0,0 +1,222 @@ +//package digital.util.util; +// +//import io.minio.*; +//import io.minio.http.Method; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.web.multipart.MultipartFile; +//import digital.base.constant.SymbolConstant; +//import digital.util.util.filter.FileTypeFilter; +//import digital.util.util.filter.StrAttackFilter; +// +//import java.io.InputStream; +//import java.net.URLDecoder; +// +///** +// * minio文件上传工具类 +// * @author: smcp +// */ +//@Slf4j +//public class MinioUtil { +// private static String minioUrl; +// private static String minioName; +// private static String minioPass; +// private static String bucketName; +// +// public static void setMinioUrl(String minioUrl) { +// MinioUtil.minioUrl = minioUrl; +// } +// +// public static void setMinioName(String minioName) { +// MinioUtil.minioName = minioName; +// } +// +// public static void setMinioPass(String minioPass) { +// MinioUtil.minioPass = minioPass; +// } +// +// public static void setBucketName(String bucketName) { +// MinioUtil.bucketName = bucketName; +// } +// +// public static String getMinioUrl() { +// return minioUrl; +// } +// +// public static String getBucketName() { +// return bucketName; +// } +// +// private static MinioClient minioClient = null; +// +// /** +// * 上传文件 +// * @param file +// * @return +// */ +// public static String upload(MultipartFile file, String bizPath, String customBucket) { +// String fileUrl = ""; +// //update-begin-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击 +// bizPath = StrAttackFilter.filter(bizPath); +// //update-end-author:wangshuai date:20201012 for: 过滤上传文件夹名特殊字符,防止攻击 +// String newBucket = bucketName; +// if(oConvertUtils.isNotEmpty(customBucket)){ +// newBucket = customBucket; +// } +// try { +// initMinio(minioUrl, minioName,minioPass); +// // 检查存储桶是否已经存在 +// if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(newBucket).build())) { +// log.info("Bucket already exists."); +// } else { +// // 创建一个名为ota的存储桶 +// minioClient.makeBucket(MakeBucketArgs.builder().bucket(newBucket).build()); +// log.info("create a new bucket."); +// } +// //update-begin-author:liusq date:20210809 for: 过滤上传文件类型 +// FileTypeFilter.fileTypeFilter(file); +// //update-end-author:liusq date:20210809 for: 过滤上传文件类型 +// InputStream stream = file.getInputStream(); +// // 获取文件名 +// String orgName = file.getOriginalFilename(); +// if("".equals(orgName)){ +// orgName=file.getName(); +// } +// orgName = CommonUtils.getFileName(orgName); +// String objectName = bizPath+"/" +// +( orgName.indexOf(".")==-1 +// ?orgName + "_" + System.currentTimeMillis() +// :orgName.substring(0, orgName.lastIndexOf(".")) + "_" + System.currentTimeMillis() + orgName.substring(orgName.lastIndexOf(".")) +// ); +// +// // 使用putObject上传一个本地文件到存储桶中。 +// if(objectName.startsWith(SymbolConstant.SINGLE_SLASH)){ +// objectName = objectName.substring(1); +// } +// PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName) +// .bucket(newBucket) +// .contentType("application/octet-stream") +// .stream(stream,stream.available(),-1).build(); +// minioClient.putObject(objectArgs); +// stream.close(); +// fileUrl = minioUrl+newBucket+"/"+objectName; +// }catch (Exception e){ +// log.error(e.getMessage(), e); +// } +// return fileUrl; +// } +// +// /** +// * 文件上传 +// * @param file +// * @param bizPath +// * @return +// */ +// public static String upload(MultipartFile file, String bizPath) { +// return upload(file,bizPath,null); +// } +// +// /** +// * 获取文件流 +// * @param bucketName +// * @param objectName +// * @return +// */ +// public static InputStream getMinioFile(String bucketName,String objectName){ +// InputStream inputStream = null; +// try { +// initMinio(minioUrl, minioName, minioPass); +// GetObjectArgs objectArgs = GetObjectArgs.builder().object(objectName) +// .bucket(bucketName).build(); +// inputStream = minioClient.getObject(objectArgs); +// } catch (Exception e) { +// log.info("文件获取失败" + e.getMessage()); +// } +// return inputStream; +// } +// +// /** +// * 删除文件 +// * @param bucketName +// * @param objectName +// * @throws Exception +// */ +// public static void removeObject(String bucketName, String objectName) { +// try { +// initMinio(minioUrl, minioName,minioPass); +// RemoveObjectArgs objectArgs = RemoveObjectArgs.builder().object(objectName) +// .bucket(bucketName).build(); +// minioClient.removeObject(objectArgs); +// }catch (Exception e){ +// log.info("文件删除失败" + e.getMessage()); +// } +// } +// +// /** +// * 获取文件外链 +// * @param bucketName +// * @param objectName +// * @param expires +// * @return +// */ +// public static String getObjectUrl(String bucketName, String objectName, Integer expires) { +// initMinio(minioUrl, minioName,minioPass); +// try{ +// //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败---- +// GetPresignedObjectUrlArgs objectArgs = GetPresignedObjectUrlArgs.builder().object(objectName) +// .bucket(bucketName) +// .expiry(expires).method(Method.GET).build(); +// //update-begin---author:liusq Date:20220121 for:获取文件外链报错提示method不能为空,导致文件下载和预览失败---- +// String url = minioClient.getPresignedObjectUrl(objectArgs); +// return URLDecoder.decode(url,"UTF-8"); +// }catch (Exception e){ +// log.info("文件路径获取失败" + e.getMessage()); +// } +// return null; +// } +// +// /** +// * 初始化客户端 +// * @param minioUrl +// * @param minioName +// * @param minioPass +// * @return +// */ +// private static MinioClient initMinio(String minioUrl, String minioName,String minioPass) { +// if (minioClient == null) { +// try { +// minioClient = MinioClient.builder() +// .endpoint(minioUrl) +// .credentials(minioName, minioPass) +// .build(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// return minioClient; +// } +// +// /** +// * 上传文件到minio +// * @param stream +// * @param relativePath +// * @return +// */ +// public static String upload(InputStream stream,String relativePath) throws Exception { +// initMinio(minioUrl, minioName,minioPass); +// if(minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) { +// log.info("Bucket already exists."); +// } else { +// // 创建一个名为ota的存储桶 +// minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build()); +// log.info("create a new bucket."); +// } +// PutObjectArgs objectArgs = PutObjectArgs.builder().object(relativePath) +// .bucket(bucketName) +// .contentType("application/octet-stream") +// .stream(stream,stream.available(),-1).build(); +// minioClient.putObject(objectArgs); +// stream.close(); +// return minioUrl+bucketName+"/"+relativePath; +// } +// +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/MyClassLoader.java b/digital-common/digital-util/src/main/java/digital/util/util/MyClassLoader.java new file mode 100644 index 0000000..a7febfe --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/MyClassLoader.java @@ -0,0 +1,106 @@ +package digital.util.util; + + +import digital.base.constant.SymbolConstant; + +/** + * @Author 张代浩 + */ +public class MyClassLoader extends ClassLoader { + public static Class getClassByScn(String className) { + Class myclass = null; + try { + myclass = Class.forName(className); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + throw new RuntimeException(className+" not found!"); + } + return myclass; + } + + /** + * 获得类的全名,包括包名 + * @param object + * @return + */ + public static String getPackPath(Object object) { + // 检查用户传入的参数是否为空 + if (object == null) { + throw new java.lang.IllegalArgumentException("参数不能为空!"); + } + // 获得类的全名,包括包名 + String clsName = object.getClass().getName(); + return clsName; + } + + public static String getAppPath(Class cls) { + // 检查用户传入的参数是否为空 + if (cls == null) { + throw new java.lang.IllegalArgumentException("参数不能为空!"); + } + ClassLoader loader = cls.getClassLoader(); + // 获得类的全名,包括包名 + String clsName = cls.getName() + ".class"; + // 获得传入参数所在的包 + Package pack = cls.getPackage(); + String path = ""; + // 如果不是匿名包,将包名转化为路径 + if (pack != null) { + String packName = pack.getName(); + String javaSpot="java."; + String javaxSpot="javax."; + // 此处简单判定是否是Java基础类库,防止用户传入JDK内置的类库 + if (packName.startsWith(javaSpot) || packName.startsWith(javaxSpot)) { + throw new java.lang.IllegalArgumentException("不要传送系统类!"); + } + // 在类的名称中,去掉包名的部分,获得类的文件名 + clsName = clsName.substring(packName.length() + 1); + // 判定包名是否是简单包名,如果是,则直接将包名转换为路径, + if (packName.indexOf(SymbolConstant.SPOT) < 0) { + path = packName + "/"; + } else { + // 否则按照包名的组成部分,将包名转换为路径 + int start = 0, end = 0; + end = packName.indexOf("."); + StringBuilder pathBuilder = new StringBuilder(); + while (end != -1) { + pathBuilder.append(packName, start, end).append("/"); + start = end + 1; + end = packName.indexOf(".", start); + } + if(oConvertUtils.isNotEmpty(pathBuilder.toString())){ + path = pathBuilder.toString(); + } + path = path + packName.substring(start) + "/"; + } + } + // 调用ClassLoader的getResource方法,传入包含路径信息的类文件名 + java.net.URL url = loader.getResource(path + clsName); + // 从URL对象中获取路径信息 + String realPath = url.getPath(); + // 去掉路径信息中的协议名"file:" + int pos = realPath.indexOf("file:"); + if (pos > -1) { + realPath = realPath.substring(pos + 5); + } + // 去掉路径信息最后包含类文件信息的部分,得到类所在的路径 + pos = realPath.indexOf(path + clsName); + realPath = realPath.substring(0, pos - 1); + // 如果类文件被打包到JAR等文件中时,去掉对应的JAR等打包文件名 + if (realPath.endsWith(SymbolConstant.EXCLAMATORY_MARK)) { + realPath = realPath.substring(0, realPath.lastIndexOf("/")); + } + /*------------------------------------------------------------ + ClassLoader的getResource方法使用了utf-8对路径信息进行了编码,当路径 + 中存在中文和空格时,他会对这些字符进行转换,这样,得到的往往不是我们想要 + 的真实路径,在此,调用了URLDecoder的decode方法进行解码,以便得到原始的 + 中文及空格路径 + -------------------------------------------------------------*/ + try { + realPath = java.net.URLDecoder.decode(realPath, "utf-8"); + } catch (Exception e) { + throw new RuntimeException(e); + } + return realPath; + }// getAppPath定义结束 +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/PasswordUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/PasswordUtil.java new file mode 100644 index 0000000..56a9d91 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/PasswordUtil.java @@ -0,0 +1,191 @@ +package digital.util.util; + +import javax.crypto.Cipher; +import javax.crypto.SecretKey; +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.PBEKeySpec; +import javax.crypto.spec.PBEParameterSpec; +import java.security.Key; +import java.security.SecureRandom; + +/** + * @Description: 密码工具类 + * @author: smcp + */ +public class PasswordUtil { + + /** + * JAVA6支持以下任意一种算法 PBEWITHMD5ANDDES PBEWITHMD5ANDTRIPLEDES + * PBEWITHSHAANDDESEDE PBEWITHSHA1ANDRC2_40 PBKDF2WITHHMACSHA1 + * */ + + /** + * 定义使用的算法为:PBEWITHMD5andDES算法 + * 加密算法 + */ + public static final String ALGORITHM = "PBEWithMD5AndDES"; + + /** + * 定义使用的算法为:PBEWITHMD5andDES算法 + * 密钥 + */ + public static final String SALT = "63293188"; + + /** + * 定义迭代次数为1000次 + */ + private static final int ITERATIONCOUNT = 1000; + + /** + * 获取加密算法中使用的盐值,解密中使用的盐值必须与加密中使用的相同才能完成操作. 盐长度必须为8字节 + * + * @return byte[] 盐值 + * */ + public static byte[] getSalt() throws Exception { + // 实例化安全随机数 + SecureRandom random = new SecureRandom(); + // 产出盐 + return random.generateSeed(8); + } + + public static byte[] getStaticSalt() { + // 产出盐 + return SALT.getBytes(); + } + + /** + * 根据PBE密码生成一把密钥 + * + * @param password + * 生成密钥时所使用的密码 + * @return Key PBE算法密钥 + * */ + private static Key getPbeKey(String password) { + // 实例化使用的算法 + SecretKeyFactory keyFactory; + SecretKey secretKey = null; + try { + keyFactory = SecretKeyFactory.getInstance(ALGORITHM); + // 设置PBE密钥参数 + PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray()); + // 生成密钥 + secretKey = keyFactory.generateSecret(keySpec); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return secretKey; + } + + /** + * 加密明文字符串 + * + * @param plaintext + * 待加密的明文字符串 + * @param password + * 生成密钥时所使用的密码 + * @param salt + * 盐值 + * @return 加密后的密文字符串 + * @throws Exception + */ + public static String encrypt(String plaintext, String password, String salt) { + + Key key = getPbeKey(password); + byte[] encipheredData = null; + PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT); + try { + Cipher cipher = Cipher.getInstance(ALGORITHM); + + cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec); + //update-begin-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7 + encipheredData = cipher.doFinal(plaintext.getBytes("utf-8")); + //update-end-author:sccott date:20180815 for:中文作为用户名时,加密的密码windows和linux会得到不同的结果 gitee/issues/IZUD7 + } catch (Exception e) { + } + return bytesToHexString(encipheredData); + } + + /** + * 解密密文字符串 + * + * @param ciphertext + * 待解密的密文字符串 + * @param password + * 生成密钥时所使用的密码(如需解密,该参数需要与加密时使用的一致) + * @param salt + * 盐值(如需解密,该参数需要与加密时使用的一致) + * @return 解密后的明文字符串 + * @throws Exception + */ + public static String decrypt(String ciphertext, String password, String salt) { + + Key key = getPbeKey(password); + byte[] passDec = null; + PBEParameterSpec parameterSpec = new PBEParameterSpec(salt.getBytes(), ITERATIONCOUNT); + try { + Cipher cipher = Cipher.getInstance(ALGORITHM); + + cipher.init(Cipher.DECRYPT_MODE, key, parameterSpec); + + passDec = cipher.doFinal(hexStringToBytes(ciphertext)); + } + + catch (Exception e) { + // TODO: handle exception + } + return new String(passDec); + } + + /** + * 将字节数组转换为十六进制字符串 + * + * @param src + * 字节数组 + * @return + */ + public static String bytesToHexString(byte[] src) { + StringBuilder stringBuilder = new StringBuilder(""); + if (src == null || src.length <= 0) { + return null; + } + for (int i = 0; i < src.length; i++) { + int v = src[i] & 0xFF; + String hv = Integer.toHexString(v); + if (hv.length() < 2) { + stringBuilder.append(0); + } + stringBuilder.append(hv); + } + return stringBuilder.toString(); + } + + /** + * 将十六进制字符串转换为字节数组 + * + * @param hexString + * 十六进制字符串 + * @return + */ + public static byte[] hexStringToBytes(String hexString) { + if (hexString == null || "".equals(hexString)) { + return null; + } + hexString = hexString.toUpperCase(); + int length = hexString.length() / 2; + char[] hexChars = hexString.toCharArray(); + byte[] d = new byte[length]; + for (int i = 0; i < length; i++) { + int pos = i * 2; + d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1])); + } + return d; + } + + private static byte charToByte(char c) { + return (byte) "0123456789ABCDEF".indexOf(c); + } + + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/PathMatcherUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/PathMatcherUtil.java new file mode 100644 index 0000000..e3c38c6 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/PathMatcherUtil.java @@ -0,0 +1,97 @@ +package digital.util.util; + +import org.springframework.util.AntPathMatcher; + +import java.util.Collection; +import java.util.Map; + +/** + * 使用Spring自身提供的地址匹配工具匹配URL + * + * @author: smcp + */ +public class PathMatcherUtil { + + public static void main(String[] args) { + String url = "/sys/dict/loadDictOrderByValue/tree,s2,2"; + String p = "/sys/dict/loadDictOrderByValue/*"; + + System.out.println(PathMatcherUtil.match(p,url)); + } + + /** + * 实际验证路径匹配权限 + * + * @param matchPath 权限url + * @param path 访问路径 + * @return 是否拥有权限 + */ + public static boolean match(String matchPath, String path) { + SpringAntMatcher springAntMatcher = new SpringAntMatcher(matchPath, true); + return springAntMatcher.matches(path); + } + + /** + * 实际验证路径匹配权限 + * + * @param list 权限url + * @param path 访问路径 + * @return 是否拥有权限 + */ + public static boolean matches(Collection list, String path) { + for (String s : list) { + SpringAntMatcher springAntMatcher = new SpringAntMatcher(s, true); + if (springAntMatcher.matches(path)) { + return true; + } + } + return false; + } + + /** + * 地址表达式匹配工具 + */ + private static class SpringAntMatcher implements Matcher { + private final AntPathMatcher antMatcher; + private final String pattern; + + private SpringAntMatcher(String pattern, boolean caseSensitive) { + this.pattern = pattern; + this.antMatcher = createMatcher(caseSensitive); + } + + @Override + public boolean matches(String path) { + return this.antMatcher.match(this.pattern, path); + } + + @Override + public Map extractUriTemplateVariables(String path) { + return this.antMatcher.extractUriTemplateVariables(this.pattern, path); + } + + private static AntPathMatcher createMatcher(boolean caseSensitive) { + AntPathMatcher matcher = new AntPathMatcher(); + matcher.setTrimTokens(false); + matcher.setCaseSensitive(caseSensitive); + return matcher; + } + } + + private interface Matcher { + + /** + * 实际验证路径匹配权限 + * @param var1 + * @return + */ + boolean matches(String var1); + + /** + * 提取path中匹配到的部分 + * @param var1 + * @return + */ + Map extractUriTemplateVariables(String var1); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/PmsUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/PmsUtil.java new file mode 100644 index 0000000..e185125 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/PmsUtil.java @@ -0,0 +1,65 @@ +package digital.util.util; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.Date; +import java.util.List; + +/** + * @Description: PmsUtil + * @author: smcp + */ +@Slf4j +@Component +public class PmsUtil { + + + private static String uploadPath; + + @Value("${jeecg.path.upload}") + public void setUploadPath(String uploadPath) { + PmsUtil.uploadPath = uploadPath; + } + + public static String saveErrorTxtByList(List msg, String name) { + Date d = new Date(); + String saveDir = "logs" + File.separator + DateUtils.yyyyMMdd.get().format(d) + File.separator; + String saveFullDir = uploadPath + File.separator + saveDir; + + File saveFile = new File(saveFullDir); + if (!saveFile.exists()) { + saveFile.mkdirs(); + } + name += DateUtils.yyyymmddhhmmss.get().format(d) + Math.round(Math.random() * 10000); + String saveFilePath = saveFullDir + name + ".txt"; + + try { + //封装目的地 + BufferedWriter bw = new BufferedWriter(new FileWriter(saveFilePath)); + //遍历集合 + for (String s : msg) { + //写数据 + if (s.indexOf("_") > 0) { + String[] arr = s.split("_"); + bw.write("第" + arr[0] + "行:" + arr[1]); + } else { + bw.write(s); + } + //bw.newLine(); + bw.write("\r\n"); + } + //释放资源 + bw.flush(); + bw.close(); + } catch (Exception e) { + log.info("excel导入生成错误日志文件异常:" + e.getMessage()); + } + return saveDir + name + ".txt"; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/ProvinceCityArea.java b/digital-common/digital-util/src/main/java/digital/util/util/ProvinceCityArea.java new file mode 100644 index 0000000..0403095 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/ProvinceCityArea.java @@ -0,0 +1,199 @@ +//package digital.util.util; +// +//import org.springframework.stereotype.Component; +//import java.io.File; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Scanner; +// +///** +// * @Description: 省市区 +// * @author: smcp +// */ +//@Component("pca") +//public class ProvinceCityArea { +// List areaList; +// +// public String getText(String code) { +// this.initAreaList(); +// if (this.areaList != null || this.areaList.size() > 0) { +// List ls = new ArrayList(); +// getAreaByCode(code, ls); +// return String.join("/", ls); +// } +// return ""; +// } +// +// public String getCode(String text) { +// this.initAreaList(); +// if (areaList != null && areaList.size() > 0) { +// for (int i = areaList.size() - 1; i >= 0; i--) { +// if (text.indexOf(areaList.get(i).getText()) >= 0) { +// return areaList.get(i).getId(); +// } +// } +// } +// return null; +// } +// +// // update-begin-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省 +// +// /** +// * 获取省市区code,精准匹配 +// * +// * @param texts 文本数组,省,市,区 +// * @return 返回 省市区的code +// */ +// public String[] getCode(String[] texts) { +// if (texts == null || texts.length == 0) { +// return null; +// } +// this.initAreaList(); +// if (areaList == null || areaList.size() == 0) { +// return null; +// } +// String[] codes = new String[texts.length]; +// String code = null; +// for (int i = 0; i < texts.length; i++) { +// String text = texts[i]; +// Area userFile; +// if (code == null) { +// userFile = getAreaByText(text); +// } else { +// userFile = getAreaByPidAndText(code, text); +// } +// if (userFile != null) { +// code = userFile.id; +// codes[i] = code; +// } else { +// return null; +// } +// } +// return codes; +// } +// +// /** +// * 根据text获取area +// * +// * @param text +// * @return +// */ +// public Area getAreaByText(String text) { +// for (Area userFile : areaList) { +// if (text.equals(userFile.getText())) { +// return userFile; +// } +// } +// return null; +// } +// +// /** +// * 通过pid获取 userFile 对象 +// * +// * @param pCode 父级编码 +// * @param text +// * @return +// */ +// public Area getAreaByPidAndText(String pCode, String text) { +// this.initAreaList(); +// if (this.areaList != null && this.areaList.size() > 0) { +// for (Area userFile : this.areaList) { +// if (userFile.getPid().equals(pCode) && userFile.getText().equals(text)) { +// return userFile; +// } +// } +// } +// return null; +// } +// // update-end-author:sunjianlei date:20220121 for:【JTC-704】数据导入错误 省市区组件,文件中为北京市,导入后,导为了山西省 +// +// public void getAreaByCode(String code, List ls) { +// for (Area userFile : areaList) { +// if (userFile.getId().equals(code)) { +// String pid = userFile.getPid(); +// ls.add(0, userFile.getText()); +// getAreaByCode(pid, ls); +// } +// } +// } +//// +//// private void initAreaList() { +//// //System.out.println("====================="); +//// if (this.areaList == null || this.areaList.size() == 0) { +//// this.areaList = new ArrayList(); +//// try { +//// String jsonData = oConvertUtils.readStatic("classpath:static/pca.json"); +//// JSONObject baseJson = JSONObject.parseObject(jsonData); +//// //第一层 省 +//// JSONObject provinceJson = baseJson.getJSONObject("86"); +//// for (String provinceKey : provinceJson.keySet()) { +//// //System.out.println("===="+provinceKey); +//// Area province = new Area(provinceKey, provinceJson.getString(provinceKey), "86"); +//// this.areaList.add(province); +//// //第二层 市 +//// JSONObject cityJson = baseJson.getJSONObject(provinceKey); +//// for (String cityKey : cityJson.keySet()) { +//// //System.out.println("-----"+cityKey); +//// Area city = new Area(cityKey, cityJson.getString(cityKey), provinceKey); +//// this.areaList.add(city); +//// //第三层 区 +//// JSONObject areaJson = baseJson.getJSONObject(cityKey); +//// if (areaJson != null) { +//// for (String areaKey : areaJson.keySet()) { +//// //System.out.println("········"+areaKey); +//// Area userFile = new Area(areaKey, areaJson.getString(areaKey), cityKey); +//// this.areaList.add(userFile); +//// } +//// } +//// } +//// } +//// } catch (Exception e) { +//// e.printStackTrace(); +//// } +//// } +//// +//// } +// +// +// private String jsonRead(File file) { +// Scanner scanner = null; +// StringBuilder buffer = new StringBuilder(); +// try { +// scanner = new Scanner(file, "utf-8"); +// while (scanner.hasNextLine()) { +// buffer.append(scanner.nextLine()); +// } +// } catch (Exception e) { +// +// } finally { +// if (scanner != null) { +// scanner.close(); +// } +// } +// return buffer.toString(); +// } +// +// class Area { +// String id; +// String text; +// String pid; +// +// public Area(String id, String text, String pid) { +// this.id = id; +// this.text = text; +// this.pid = pid; +// } +// +// public String getId() { +// return id; +// } +// +// public String getText() { +// return text; +// } +// +// public String getPid() { +// return pid; +// } +// } +//} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/ReflectHelper.java b/digital-common/digital-util/src/main/java/digital/util/util/ReflectHelper.java new file mode 100644 index 0000000..9513d65 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/ReflectHelper.java @@ -0,0 +1,255 @@ +package digital.util.util; + +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; +import java.util.Map.Entry; +import java.util.regex.Pattern; + +/** + * @author 张代浩 + * @desc 通过反射来动态调用get 和 set 方法 + */ +@Slf4j +public class ReflectHelper { + + private Class cls; + + /** + * 传过来的对象 + */ + private Object obj; + + /** + * 存放get方法 + */ + private Hashtable getMethods = null; + /** + * 存放set方法 + */ + private Hashtable setMethods = null; + + /** + * 定义构造方法 -- 一般来说是个pojo + * + * @param o 目标对象 + */ + public ReflectHelper(Object o) { + obj = o; + initMethods(); + } + + /** + * @desc 初始化 + */ + public void initMethods() { + getMethods = new Hashtable(); + setMethods = new Hashtable(); + cls = obj.getClass(); + Method[] methods = cls.getMethods(); + // 定义正则表达式,从方法中过滤出getter / setter 函数. + String gs = "get(\\w+)"; + Pattern getM = Pattern.compile(gs); + String ss = "set(\\w+)"; + Pattern setM = Pattern.compile(ss); + // 把方法中的"set" 或者 "get" 去掉 + String rapl = "$1"; + String param; + for (int i = 0; i < methods.length; ++i) { + Method m = methods[i]; + String methodName = m.getName(); + if (Pattern.matches(gs, methodName)) { + param = getM.matcher(methodName).replaceAll(rapl).toLowerCase(); + getMethods.put(param, m); + } else if (Pattern.matches(ss, methodName)) { + param = setM.matcher(methodName).replaceAll(rapl).toLowerCase(); + setMethods.put(param, m); + } else { + // logger.info(methodName + " 不是getter,setter方法!"); + } + } + } + + /** + * @desc 调用set方法 + */ + public boolean setMethodValue(String property, Object object) { + Method m = setMethods.get(property.toLowerCase()); + if (m != null) { + try { + // 调用目标类的setter函数 + m.invoke(obj, object); + return true; + } catch (Exception ex) { + log.info("invoke getter on " + property + " error: " + ex.toString()); + return false; + } + } + return false; + } + + /** + * @desc 调用set方法 + */ + public Object getMethodValue(String property) { + Object value = null; + Method m = getMethods.get(property.toLowerCase()); + if (m != null) { + try { + /* + * 调用obj类的setter函数 + */ + value = m.invoke(obj, new Object[]{}); + + } catch (Exception ex) { + log.info("invoke getter on " + property + " error: " + ex.toString()); + } + } + return value; + } + + /** + * 把map中的内容全部注入到obj中 + * + * @param data + * @return + */ + public Object setAll(Map data) { + if (data == null || data.keySet().size() <= 0) { + return null; + } + for (Entry entry : data.entrySet()) { + this.setMethodValue(entry.getKey(), entry.getValue()); + } + return obj; + } + + /** + * 把map中的内容全部注入到obj中 + * + * @param o + * @param data + * @return + */ + public static Object setAll(Object o, Map data) { + ReflectHelper reflectHelper = new ReflectHelper(o); + reflectHelper.setAll(data); + return o; + } + + /** + * 把map中的内容全部注入到新实例中 + * + * @param clazz + * @param data + * @return + */ + @SuppressWarnings("unchecked") + public static T setAll(Class clazz, Map data) { + T o = null; + try { + o = clazz.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + o = null; + return o; + } + return (T) setAll(o, data); + } + + /** + * 根据传入的class将mapList转换为实体类list + * + * @param mapist + * @param clazz + * @return + */ + public static List transList2Entrys(List> mapist, Class clazz) { + List list = new ArrayList(); + if (mapist != null && mapist.size() > 0) { + for (Map data : mapist) { + list.add(ReflectHelper.setAll(clazz, data)); + } + } + return list; + } + + /** + * 根据属性名获取属性值 + */ + public static Object getFieldValueByName(String fieldName, Object o) { + try { + String firstLetter = fieldName.substring(0, 1).toUpperCase(); + String getter = "get" + firstLetter + fieldName.substring(1); + Method method = o.getClass().getMethod(getter, new Class[]{}); + Object value = method.invoke(o, new Object[]{}); + return value; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取属性值 + */ + public static Object getFieldVal(String fieldName, Object o) { + try { + // 暴力反射获取属性 + Field filed = o.getClass().getDeclaredField(fieldName); + // 设置反射时取消Java的访问检查,暴力访问 + filed.setAccessible(true); + Object val = filed.get(o); + return val; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 获取属性名数组 + */ + public static String[] getFiledName(Object o) { + Field[] fields = o.getClass().getDeclaredFields(); + String[] fieldNames = new String[fields.length]; + for (int i = 0; i < fields.length; i++) { + //log.info(fields[i].getType()); + fieldNames[i] = fields[i].getName(); + } + return fieldNames; + } + + /** + * 获取属性类型(type),属性名(name),属性值(value)的map组成的list + */ + public static List getFiledsInfo(Object o) { + Field[] fields = o.getClass().getDeclaredFields(); + String[] fieldNames = new String[fields.length]; + List list = new ArrayList(); + Map infoMap = null; + for (int i = 0; i < fields.length; i++) { + infoMap = new HashMap<>(5); + infoMap.put("type", fields[i].getType().toString()); + infoMap.put("name", fields[i].getName()); + infoMap.put("value", getFieldValueByName(fields[i].getName(), o)); + list.add(infoMap); + } + return list; + } + + /** + * 获取对象的所有属性值,返回一个对象数组 + */ + public static Object[] getFiledValues(Object o) { + String[] fieldNames = getFiledName(o); + Object[] value = new Object[fieldNames.length]; + for (int i = 0; i < fieldNames.length; i++) { + value[i] = getFieldValueByName(fieldNames[i], o); + } + return value; + } + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/RestDesformUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/RestDesformUtil.java new file mode 100644 index 0000000..aa9c2e4 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/RestDesformUtil.java @@ -0,0 +1,122 @@ +package digital.util.util; + +import com.alibaba.fastjson.JSONObject; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import digital.base.vo.Result; + + +/** + * 通过 RESTful 风格的接口操纵 desform 里的数据 + * + * @author sunjianlei + */ +public class RestDesformUtil { + + private static String domain = null; + private static String path = null; + + static { + domain = SpringContextUtils.getDomain(); + path = oConvertUtils.getString(SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path")); + } + + /** + * 查询数据 + * + * @param desformCode + * @param dataId + * @param token + * @return + */ + public static Result queryOne(String desformCode, String dataId, String token) { + String url = getBaseUrl(desformCode, dataId).toString(); + HttpHeaders headers = getHeaders(token); + ResponseEntity result = RestUtil.request(url, HttpMethod.GET, headers, null, null, JSONObject.class); + return packageReturn(result); + } + + /** + * 新增数据 + * + * @param desformCode + * @param formData + * @param token + * @return + */ + public static Result addOne(String desformCode, JSONObject formData, String token) { + return addOrEditOne(desformCode, formData, token, HttpMethod.POST); + } + + /** + * 修改数据 + * + * @param desformCode + * @param formData + * @param token + * @return + */ + public static Result editOne(String desformCode, JSONObject formData, String token) { + return addOrEditOne(desformCode, formData, token, HttpMethod.PUT); + } + + private static Result addOrEditOne(String desformCode, JSONObject formData, String token, HttpMethod method) { + String url = getBaseUrl(desformCode).toString(); + HttpHeaders headers = getHeaders(token); + ResponseEntity result = RestUtil.request(url, method, headers, null, formData, JSONObject.class); + return packageReturn(result); + } + + /** + * 删除数据 + * + * @param desformCode + * @param dataId + * @param token + * @return + */ + public static Result removeOne(String desformCode, String dataId, String token) { + String url = getBaseUrl(desformCode, dataId).toString(); + HttpHeaders headers = getHeaders(token); + ResponseEntity result = RestUtil.request(url, HttpMethod.DELETE, headers, null, null, JSONObject.class); + return packageReturn(result); + } + + private static Result packageReturn(ResponseEntity result) { + if (result.getBody() != null) { + return result.getBody().toJavaObject(Result.class); + } + return Result.error("操作失败"); + } + + private static StringBuilder getBaseUrl() { + StringBuilder builder = new StringBuilder(domain).append(path); + builder.append("/desform/api"); + return builder; + } + + private static StringBuilder getBaseUrl(String desformCode, String dataId) { + StringBuilder builder = getBaseUrl(); + builder.append("/").append(desformCode); + if (dataId != null) { + builder.append("/").append(dataId); + } + return builder; + } + + private static StringBuilder getBaseUrl(String desformCode) { + return getBaseUrl(desformCode, null); + } + + private static HttpHeaders getHeaders(String token) { + HttpHeaders headers = new HttpHeaders(); + String mediaType = MediaType.APPLICATION_JSON_UTF8_VALUE; + headers.setContentType(MediaType.parseMediaType(mediaType)); + headers.set("Accept", mediaType); + headers.set("X-Access-Token", token); + return headers; + } + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/RestUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/RestUtil.java new file mode 100644 index 0000000..8099ab8 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/RestUtil.java @@ -0,0 +1,328 @@ +package digital.util.util; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cloud.client.loadbalancer.LoadBalanced; +import org.springframework.http.*; +import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.converter.StringHttpMessageConverter; +import org.springframework.util.StringUtils; +import org.springframework.web.client.RestTemplate; +import java.nio.charset.StandardCharsets; +import java.util.Iterator; +import java.util.Map; + +/** + * 调用 Restful 接口 Util + * + * @author sunjianlei + */ +@Slf4j +public class RestUtil { + + private static String domain = null; + + public static String getDomain() { + if (domain == null) { + domain = SpringContextUtils.getDomain(); + // issues/2959 + // 微服务版集成企业微信单点登录 + // 因为微服务版没有端口号,导致 SpringContextUtils.getDomain() 方法获取的域名的端口号变成了:-1所以出问题了,只需要把这个-1给去掉就可以了。 + String port=":-1"; + if (domain.endsWith(port)) { + domain = domain.substring(0, domain.length() - 3); + } + } + return domain; + } + + public static String path = null; + + public static String getPath() { + if (path == null) { + path = SpringContextUtils.getApplicationContext().getEnvironment().getProperty("server.servlet.context-path"); + } + return oConvertUtils.getString(path); + } + + public static String getBaseUrl() { + String basepath = getDomain() + getPath(); + log.info(" RestUtil.getBaseUrl: " + basepath); + return basepath; + } + + /** + * RestAPI 调用器 + */ + @LoadBalanced + private final static RestTemplate RT; + + static { + SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); + requestFactory.setConnectTimeout(7200*1000); + requestFactory.setReadTimeout(7200*1000); + RT = new RestTemplate(requestFactory); + // 解决乱码问题 + RT.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8)); + } + + public static RestTemplate getRestTemplate() { + return RT; + } + + /** + * 发送 get 请求 + */ + public static JSONObject get(String url) { + return getNative(url, null, null).getBody(); + } + + /** + * 发送 get 请求 + */ + public static JSONObject get(String url, JSONObject variables) { + return getNative(url, variables, null).getBody(); + } + + /** + * 发送 get 请求 + */ + public static JSONObject get(String url, JSONObject variables, JSONObject params) { + return getNative(url, variables, params).getBody(); + } + + /** + * 发送 get 请求,返回原生 ResponseEntity 对象 + */ + public static ResponseEntity getNative(String url, JSONObject variables, JSONObject params) { + return request(url, HttpMethod.GET, variables, params); + } + + /** + * 发送 Post 请求 + */ + public static JSONObject post(String url) { + return postNative(url, null, null).getBody(); + } + + /** + * 发送 Post 请求 + */ + public static JSONObject post(String url, JSONObject params) { + return postNative(url, null, params).getBody(); + } + + /** + * 发送 Post 请求 + */ + public static JSONObject post(String url, JSONObject variables, JSONObject params) { + return postNative(url, variables, params).getBody(); + } + + /** + * 发送 POST 请求,返回原生 ResponseEntity 对象 + */ + public static ResponseEntity postNative(String url, JSONObject variables, JSONObject params) { + return request(url, HttpMethod.POST, variables, params); + } + + /** + * 发送 put 请求 + */ + public static JSONObject put(String url) { + return putNative(url, null, null).getBody(); + } + + /** + * 发送 put 请求 + */ + public static JSONObject put(String url, JSONObject params) { + return putNative(url, null, params).getBody(); + } + + /** + * 发送 put 请求 + */ + public static JSONObject put(String url, JSONObject variables, JSONObject params) { + return putNative(url, variables, params).getBody(); + } + + /** + * 发送 put 请求,返回原生 ResponseEntity 对象 + */ + public static ResponseEntity putNative(String url, JSONObject variables, JSONObject params) { + return request(url, HttpMethod.PUT, variables, params); + } + + /** + * 发送 delete 请求 + */ + public static JSONObject delete(String url) { + return deleteNative(url, null, null).getBody(); + } + + /** + * 发送 delete 请求 + */ + public static JSONObject delete(String url, JSONObject variables, JSONObject params) { + return deleteNative(url, variables, params).getBody(); + } + + /** + * 发送 delete 请求,返回原生 ResponseEntity 对象 + */ + public static ResponseEntity deleteNative(String url, JSONObject variables, JSONObject params) { + return request(url, HttpMethod.DELETE, null, variables, params, JSONObject.class); + } + + /** + * 发送请求 + */ + public static ResponseEntity request(String url, HttpMethod method, JSONObject variables, JSONObject params) { + return request(url, method, getHeaderApplicationJson(), variables, params, JSONObject.class); + } + + /** + * 发送请求 + * + * @param url 请求地址 + * @param method 请求方式 + * @param headers 请求头 可空 + * @param variables 请求url参数 可空 + * @param params 请求body参数 可空 + * @param responseType 返回类型 + * @return ResponseEntity + */ + public static ResponseEntity request(String url, HttpMethod method, HttpHeaders headers, JSONObject variables, Object params, Class responseType) { + log.info(" RestUtil --- request --- url = "+ url); + if (StringUtils.isEmpty(url)) { + throw new RuntimeException("url 不能为空"); + } + if (method == null) { + throw new RuntimeException("method 不能为空"); + } + if (headers == null) { + headers = new HttpHeaders(); + } + // 请求体 + String body = ""; + if (params != null) { + if (params instanceof JSONObject) { + body = ((JSONObject) params).toJSONString(); + + } else { + body = params.toString(); + } + } + // 拼接 url 参数 + if (variables != null) { + url += ("?" + asUrlVariables(variables)); + } + // 发送请求 + HttpEntity request = new HttpEntity<>(body, headers); + return RT.exchange(url, method, request, responseType); + } + + public static ResponseEntity zitaRequest(String url, HttpMethod method, + HttpHeaders headers ,JSONObject variables, + Object params, Class responseType) { + log.info(" RestUtil --- request --- url = "+ url); + if (StringUtils.isEmpty(url)) { + throw new RuntimeException("url 不能为空"); + } + if (method == null) { + throw new RuntimeException("method 不能为空"); + } + // 请求体 + String body = ""; + if (params != null) { + if (params instanceof JSONObject) { + body = ((JSONObject) params).toJSONString(); + + } else { + body = params.toString(); + } + } + // 拼接 url 参数 + if (variables != null) { + url += ("?" + asUrlVariables(variables)); + } + // 发送请求 + HttpEntity request = new HttpEntity<>(body, headers); + return RT.exchange(url, method, request, responseType); + } + + + public static ResponseEntity zitaRequest(String url, HttpMethod method ,JSONObject variables, Object params, Class responseType) { + log.info(" RestUtil --- request --- url = "+ url); + if (StringUtils.isEmpty(url)) { + throw new RuntimeException("url 不能为空"); + } + if (method == null) { + throw new RuntimeException("method 不能为空"); + } + + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type","application/json;charset=UTF-8"); + headers.setContentType(MediaType.APPLICATION_JSON_UTF8); + headers.add("Accept", MediaType.APPLICATION_JSON.toString()); + // 请求体 + String body = ""; + if (params != null) { + if (params instanceof JSONObject) { + body = ((JSONObject) params).toJSONString(); + + } else { + body = params.toString(); + } + } + // 拼接 url 参数 + if (variables != null) { + url += ("?" + asUrlVariables(variables)); + } + // 发送请求 + HttpEntity request = new HttpEntity<>(body, headers); + return RT.exchange(url, method, request, responseType); + } + + + /** + * 获取JSON请求头 + */ + public static HttpHeaders getHeaderApplicationJson() { + return getHeader(MediaType.APPLICATION_JSON_UTF8_VALUE); + } + + /** + * 获取请求头 + */ + public static HttpHeaders getHeader(String mediaType) { + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.parseMediaType(mediaType)); + headers.add("Accept", mediaType); + return headers; + } + + /** + * 将 JSONObject 转为 a=1&b=2&c=3...&n=n 的形式 + */ + public static String asUrlVariables(JSONObject variables) { + Map source = variables.getInnerMap(); + Iterator it = source.keySet().iterator(); + StringBuilder urlVariables = new StringBuilder(); + while (it.hasNext()) { + String key = it.next(); + String value = ""; + Object object = source.get(key); + if (object != null) { + if (!StringUtils.isEmpty(object.toString())) { + value = object.toString(); + } + } + urlVariables.append("&").append(key).append("=").append(value); + } + // 去掉第一个& + return urlVariables.substring(1); + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/SpringContextHolder.java b/digital-common/digital-util/src/main/java/digital/util/util/SpringContextHolder.java new file mode 100644 index 0000000..8134fc0 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/SpringContextHolder.java @@ -0,0 +1,81 @@ + +package digital.util.util; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; + +/** + * 以静态变量保存Spring ApplicationContext, 可在任何代码任何地方任何时候中取出ApplicaitonContext. + * + * @author zyf + */ +@Slf4j +public class SpringContextHolder implements ApplicationContextAware { + private static ApplicationContext applicationContext; + + /** + * 实现ApplicationContextAware接口的context注入函数, 将其存入静态变量. + */ + @Override + public void setApplicationContext(ApplicationContext applicationContext) { + // NOSONAR + SpringContextHolder.applicationContext = applicationContext; + } + + /** + * 取得存储在静态变量中的ApplicationContext. + */ + public static ApplicationContext getApplicationContext() { + checkApplicationContext(); + return applicationContext; + } + + /** + * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(String name) { + checkApplicationContext(); + return (T) applicationContext.getBean(name); + } + + /** + * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getHandler(String name, Class cls) { + T t = null; + if (ObjectUtil.isNotEmpty(name)) { + checkApplicationContext(); + try { + t = applicationContext.getBean(name, cls); + } catch (Exception e) { + log.warn("Customize redis listener handle [ " + name + " ], does not exist!"); + } + } + return t; + } + + + /** + * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class clazz) { + checkApplicationContext(); + return applicationContext.getBean(clazz); + } + + /** + * 清除applicationContext静态变量. + */ + public static void cleanApplicationContext() { + applicationContext = null; + } + + private static void checkApplicationContext() { + if (applicationContext == null) { + throw new IllegalStateException("applicaitonContext未注入,请在applicationContext.xml中定义SpringContextHolder"); + } + } + +} \ No newline at end of file diff --git a/digital-common/digital-util/src/main/java/digital/util/util/SpringContextUtils.java b/digital-common/digital-util/src/main/java/digital/util/util/SpringContextUtils.java new file mode 100644 index 0000000..1de32de --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/SpringContextUtils.java @@ -0,0 +1,108 @@ +package digital.util.util; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.stereotype.Component; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import digital.base.constant.ServiceNameConstants; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Description: spring上下文工具类 + * @author: smcp + */ +@Component +public class SpringContextUtils implements ApplicationContextAware { + + /** + * 上下文对象实例 + */ + private static ApplicationContext applicationContext; + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + SpringContextUtils.applicationContext = applicationContext; + } + + /** + * 获取applicationContext + * + * @return + */ + public static ApplicationContext getApplicationContext() { + return applicationContext; + } + + /** + * 获取HttpServletRequest + */ + public static HttpServletRequest getHttpServletRequest() { + if (RequestContextHolder.getRequestAttributes() == null) { + return null; + } + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); + } + /** + * 获取HttpServletResponse + */ + public static HttpServletResponse getHttpServletResponse() { + return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse(); + } + + /** + * 获取项目根路径 basePath + */ + public static String getDomain(){ + HttpServletRequest request = getHttpServletRequest(); + StringBuffer url = request.getRequestURL(); + //微服务情况下,获取gateway的basePath + String basePath = request.getHeader(ServiceNameConstants.X_GATEWAY_BASE_PATH); + if(oConvertUtils.isNotEmpty(basePath)){ + return basePath; + }else{ + return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString(); + } + } + + public static String getOrigin(){ + HttpServletRequest request = getHttpServletRequest(); + return request.getHeader("Origin"); + } + + /** + * 通过name获取 Bean. + * + * @param name + * @return + */ + public static Object getBean(String name) { + return getApplicationContext().getBean(name); + } + + /** + * 通过class获取Bean. + * + * @param clazz + * @param + * @return + */ + public static T getBean(Class clazz) { + return getApplicationContext().getBean(clazz); + } + + /** + * 通过name,以及Clazz返回指定的Bean + * + * @param name + * @param clazz + * @param + * @return + */ + public static T getBean(String name, Class clazz) { + return getApplicationContext().getBean(name, clazz); + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/SqlInjectionUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/SqlInjectionUtil.java new file mode 100644 index 0000000..207e180 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/SqlInjectionUtil.java @@ -0,0 +1,172 @@ +package digital.util.util; + +import cn.hutool.crypto.SecureUtil; +import lombok.extern.slf4j.Slf4j; +import digital.util.exception.JeecgBootException; + +import javax.servlet.http.HttpServletRequest; +import java.util.regex.Pattern; + +/** + * sql注入处理工具类 + * + * @author zhoujf + */ +@Slf4j +public class SqlInjectionUtil { + /** + * sign 用于表字典加签的盐值【SQL漏洞】 + * (上线修改值 20200501,同步修改前端的盐值) + */ + private final static String TABLE_DICT_SIGN_SALT = "20200501"; + private final static String XSS_STR = " and |exec |insert |select |delete |update |drop |count |chr |mid |master |truncate |char |declare |;|or |+|user()"; + + /**show tables*/ + private final static String SHOW_TABLES = "show\\s+tables"; + + /** + * 针对表字典进行额外的sign签名校验(增加安全机制) + * @param dictCode: + * @param sign: + * @param request: + * @Return: void + */ + public static void checkDictTableSign(String dictCode, String sign, HttpServletRequest request) { + //表字典SQL注入漏洞,签名校验 + String accessToken = request.getHeader("X-Access-Token"); + String signStr = dictCode + SqlInjectionUtil.TABLE_DICT_SIGN_SALT + accessToken; + String javaSign = SecureUtil.md5(signStr); + if (!javaSign.equals(sign)) { + log.error("表字典,SQL注入漏洞签名校验失败 :" + sign + "!=" + javaSign+ ",dictCode=" + dictCode); + throw new JeecgBootException("无权限访问!"); + } + log.info(" 表字典,SQL注入漏洞签名校验成功!sign=" + sign + ",dictCode=" + dictCode); + } + + + /** + * sql注入过滤处理,遇到注入关键字抛异常 + * + * @param value + * @return + */ + public static void filterContent(String value) { + if (value == null || "".equals(value)) { + return; + } + // 统一转为小写 + value = value.toLowerCase(); + //SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE + value = value.replaceAll("/\\*.*\\*/",""); + + String[] xssArr = XSS_STR.split("\\|"); + for (int i = 0; i < xssArr.length; i++) { + if (value.indexOf(xssArr[i]) > -1) { + log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]); + log.error("请注意,值可能存在SQL注入风险!---> {}", value); + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + } + if(Pattern.matches(SHOW_TABLES, value)){ + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + return; + } + + /** + * sql注入过滤处理,遇到注入关键字抛异常 + * + * @param values + * @return + */ + public static void filterContent(String[] values) { + String[] xssArr = XSS_STR.split("\\|"); + for (String value : values) { + if (value == null || "".equals(value)) { + return; + } + // 统一转为小写 + value = value.toLowerCase(); + //SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE + value = value.replaceAll("/\\*.*\\*/",""); + + for (int i = 0; i < xssArr.length; i++) { + if (value.indexOf(xssArr[i]) > -1) { + log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]); + log.error("请注意,值可能存在SQL注入风险!---> {}", value); + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + } + if(Pattern.matches(SHOW_TABLES, value)){ + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + } + return; + } + + /** + * 【提醒:不通用】 + * 仅用于字典条件SQL参数,注入过滤 + * + * @param value + * @return + */ + //@Deprecated + public static void specialFilterContent(String value) { + String specialXssStr = " exec | insert | select | delete | update | drop | count | chr | mid | master | truncate | char | declare |;|+|"; + String[] xssArr = specialXssStr.split("\\|"); + if (value == null || "".equals(value)) { + return; + } + // 统一转为小写 + value = value.toLowerCase(); + //SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE + value = value.replaceAll("/\\*.*\\*/",""); + + for (int i = 0; i < xssArr.length; i++) { + if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) { + log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]); + log.error("请注意,值可能存在SQL注入风险!---> {}", value); + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + } + if(Pattern.matches(SHOW_TABLES, value)){ + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + return; + } + + + /** + * 【提醒:不通用】 + * 仅用于Online报表SQL解析,注入过滤 + * @param value + * @return + */ + //@Deprecated + public static void specialFilterContentForOnlineReport(String value) { + String specialXssStr = " exec | insert | delete | update | drop | chr | mid | master | truncate | char | declare |"; + String[] xssArr = specialXssStr.split("\\|"); + if (value == null || "".equals(value)) { + return; + } + // 统一转为小写 + value = value.toLowerCase(); + //SQL注入检测存在绕过风险 https://gitee.com/jeecg/jeecg-boot/issues/I4NZGE + value = value.replaceAll("/\\*.*\\*/",""); + + for (int i = 0; i < xssArr.length; i++) { + if (value.indexOf(xssArr[i]) > -1 || value.startsWith(xssArr[i].trim())) { + log.error("请注意,存在SQL注入关键词---> {}", xssArr[i]); + log.error("请注意,值可能存在SQL注入风险!---> {}", value); + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + } + + if(Pattern.matches(SHOW_TABLES, value)){ + throw new RuntimeException("请注意,值可能存在SQL注入风险!--->" + value); + } + return; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/SysAnnmentTypeEnum.java b/digital-common/digital-util/src/main/java/digital/util/util/SysAnnmentTypeEnum.java new file mode 100644 index 0000000..695b22b --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/SysAnnmentTypeEnum.java @@ -0,0 +1,71 @@ +package digital.util.util; + +/** + * 系统公告自定义跳转方式 + * @author: smcp + */ +public enum SysAnnmentTypeEnum { + /** + * 邮件跳转组件 + */ + EMAIL("email", "component", "modules/eoa/email/modals/EoaEmailInForm"), + /** + * 工作流跳转链接我的办公 + */ + BPM("bpm", "url", "/bpm/task/MyTaskList"); + + /** + * 业务类型(email:邮件 bpm:流程) + */ + private String type; + /** + * 打开方式 组件:component 路由:url + */ + private String openType; + /** + * 组件/路由 地址 + */ + private String openPage; + + SysAnnmentTypeEnum(String type, String openType, String openPage) { + this.type = type; + this.openType = openType; + this.openPage = openPage; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getOpenType() { + return openType; + } + + public void setOpenType(String openType) { + this.openType = openType; + } + + public String getOpenPage() { + return openPage; + } + + public void setOpenPage(String openPage) { + this.openPage = openPage; + } + + public static SysAnnmentTypeEnum getByType(String type) { + if (oConvertUtils.isEmpty(type)) { + return null; + } + for (SysAnnmentTypeEnum val : values()) { + if (val.getType().equals(type)) { + return val; + } + } + return null; + } +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/SysUserCacheInfo.java b/digital-common/digital-util/src/main/java/digital/util/util/SysUserCacheInfo.java new file mode 100644 index 0000000..b387a13 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/SysUserCacheInfo.java @@ -0,0 +1,70 @@ +package digital.util.util; + +import java.util.List; + + +/** + * @Description: 用户缓存信息 + * @author: smcp + */ +public class SysUserCacheInfo { + + private String sysUserCode; + + private String sysUserName; + + private String sysOrgCode; + + private List sysMultiOrgCode; + + private boolean oneDepart; + + public boolean isOneDepart() { + return oneDepart; + } + + public void setOneDepart(boolean oneDepart) { + this.oneDepart = oneDepart; + } + + public String getSysDate() { + return DateUtils.formatDate(); + } + + public String getSysTime() { + return DateUtils.now(); + } + + public String getSysUserCode() { + return sysUserCode; + } + + public void setSysUserCode(String sysUserCode) { + this.sysUserCode = sysUserCode; + } + + public String getSysUserName() { + return sysUserName; + } + + public void setSysUserName(String sysUserName) { + this.sysUserName = sysUserName; + } + + public String getSysOrgCode() { + return sysOrgCode; + } + + public void setSysOrgCode(String sysOrgCode) { + this.sysOrgCode = sysOrgCode; + } + + public List getSysMultiOrgCode() { + return sysMultiOrgCode; + } + + public void setSysMultiOrgCode(List sysMultiOrgCode) { + this.sysMultiOrgCode = sysMultiOrgCode; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/UUIDGenerator.java b/digital-common/digital-util/src/main/java/digital/util/util/UUIDGenerator.java new file mode 100644 index 0000000..cca872e --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/UUIDGenerator.java @@ -0,0 +1,96 @@ +package digital.util.util; + + +import java.net.InetAddress; + +/** + * + * @Author 张代浩 + * + */ +public class UUIDGenerator { + + + /** + * 产生一个32位的UUID + * + * @return + */ + + public static String generate() { + return new StringBuilder(32).append(format(getIp())).append( + format(getJvm())).append(format(getHiTime())).append( + format(getLoTime())).append(format(getCount())).toString(); + + } + + private static final int IP; + static { + int ipadd; + try { + ipadd = toInt(InetAddress.getLocalHost().getAddress()); + } catch (Exception e) { + ipadd = 0; + } + IP = ipadd; + } + + private static short counter = (short) 0; + + private static final int JVM = (int) (System.currentTimeMillis() >>> 8); + + private final static String format(int intval) { + String formatted = Integer.toHexString(intval); + StringBuilder buf = new StringBuilder("00000000"); + buf.replace(8 - formatted.length(), 8, formatted); + return buf.toString(); + } + + private final static String format(short shortval) { + String formatted = Integer.toHexString(shortval); + StringBuilder buf = new StringBuilder("0000"); + buf.replace(4 - formatted.length(), 4, formatted); + return buf.toString(); + } + + private final static int getJvm() { + return JVM; + } + + private final static short getCount() { + synchronized (UUIDGenerator.class) { + if (counter < 0) { + counter = 0; + } + return counter++; + } + } + + /** + * Unique in a local network + */ + private final static int getIp() { + return IP; + } + + /** + * Unique down to millisecond + */ + private final static short getHiTime() { + return (short) (System.currentTimeMillis() >>> 32); + } + + private final static int getLoTime() { + return (int) System.currentTimeMillis(); + } + + private final static int toInt(byte[] bytes) { + int result = 0; + int length = 4; + for (int i = 0; i < length; i++) { + result = (result << 8) - Byte.MIN_VALUE + (int) bytes[i]; + } + return result; + } + +} diff --git a/digital-common/digital-util/src/main/java/digital/util/util/YouBianCodeUtil.java b/digital-common/digital-util/src/main/java/digital/util/util/YouBianCodeUtil.java new file mode 100644 index 0000000..3cefeb9 --- /dev/null +++ b/digital-common/digital-util/src/main/java/digital/util/util/YouBianCodeUtil.java @@ -0,0 +1,175 @@ +package digital.util.util; + + +/** + * 流水号生成规则(按默认规则递增,数字从1-99开始递增,数字到99,递增字母;位数不够增加位数) + * A001 + * A001A002 + * @Author zhangdaihao + * + */ +public class YouBianCodeUtil { + + // 数字位数(默认生成3位的数字) + + /**代表数字位数*/ + private static final int NUM_LENGTH = 2; + + public static final int ZHANWEI_LENGTH = 1+ NUM_LENGTH; + + public static final char LETTER= 'Z'; + + /** + * 根据前一个code,获取同级下一个code + * 例如:当前最大code为D01A04,下一个code为:D01A05 + * + * @param code + * @return + */ + public static synchronized String getNextYouBianCode(String code) { + String newcode = ""; + if (oConvertUtils.isEmpty(code)) { + String zimu = "A"; + String num = getStrNum(1); + newcode = zimu + num; + } else { + String beforeCode = code.substring(0, code.length() - 1- NUM_LENGTH); + String afterCode = code.substring(code.length() - 1 - NUM_LENGTH,code.length()); + char afterCodeZimu = afterCode.substring(0, 1).charAt(0); + Integer afterCodeNum = Integer.parseInt(afterCode.substring(1)); +// org.jeecgframework.core.util.LogUtil.info(after_code); +// org.jeecgframework.core.util.LogUtil.info(after_code_zimu); +// org.jeecgframework.core.util.LogUtil.info(after_code_num); + + String nextNum = ""; + char nextZimu = 'A'; + // 先判断数字等于999*,则计数从1重新开始,递增 + if (afterCodeNum == getMaxNumByLength(NUM_LENGTH)) { + nextNum = getNextStrNum(0); + } else { + nextNum = getNextStrNum(afterCodeNum); + } + // 先判断数字等于999*,则字母从A重新开始,递增 + if(afterCodeNum == getMaxNumByLength(NUM_LENGTH)) { + nextZimu = getNextZiMu(afterCodeZimu); + }else{ + nextZimu = afterCodeZimu; + } + + // 例如Z99,下一个code就是Z99A01 + if (LETTER == afterCodeZimu && getMaxNumByLength(NUM_LENGTH) == afterCodeNum) { + newcode = code + (nextZimu + nextNum); + } else { + newcode = beforeCode + (nextZimu + nextNum); + } + } + return newcode; + + } + + /** + * 根据父亲code,获取下级的下一个code + * + * 例如:父亲CODE:A01 + * 当前CODE:A01B03 + * 获取的code:A01B04 + * + * @param parentCode 上级code + * @param localCode 同级code + * @return + */ + public static synchronized String getSubYouBianCode(String parentCode,String localCode) { + if(localCode!=null && localCode!=""){ + +// return parentCode + getNextYouBianCode(localCode); + return getNextYouBianCode(localCode); + + }else{ + parentCode = parentCode + "A"+ getNextStrNum(0); + } + return parentCode; + } + + + + /** + * 将数字前面位数补零 + * + * @param num + * @return + */ + private static String getNextStrNum(int num) { + return getStrNum(getNextNum(num)); + } + + /** + * 将数字前面位数补零 + * + * @param num + * @return + */ + private static String getStrNum(int num) { + String s = String.format("%0" + NUM_LENGTH + "d", num); + return s; + } + + /** + * 递增获取下个数字 + * + * @param num + * @return + */ + private static int getNextNum(int num) { + num++; + return num; + } + + /** + * 递增获取下个字母 + * + * @param num + * @return + */ + private static char getNextZiMu(char zimu) { + if (zimu == LETTER) { + return 'A'; + } + zimu++; + return zimu; + } + + /** + * 根据数字位数获取最大值 + * @param length + * @return + */ + private static int getMaxNumByLength(int length){ + if(length==0){ + return 0; + } + StringBuilder maxNum = new StringBuilder(); + for (int i=0;i netInterfaces = NetworkInterface.getNetworkInterfaces(); + InetAddress ip = null; + // 是否找到外网IP + boolean finded = false; + while (netInterfaces.hasMoreElements() && !finded) { + NetworkInterface ni = netInterfaces.nextElement(); + Enumeration address = ni.getInetAddresses(); + while (address.hasMoreElements()) { + ip = address.nextElement(); + // 外网IP + if (!ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) { + netip = ip.getHostAddress(); + finded = true; + break; + } else if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && ip.getHostAddress().indexOf(":") == -1) { + // 内网IP + localip = ip.getHostAddress(); + } + } + } + + if (netip != null && !"".equals(netip)) { + return netip; + } else { + return localip; + } + } + + /** + * java去除字符串中的空格、回车、换行符、制表符 + * + * @param str + * @return + */ + public static String replaceBlank(String str) { + String dest = ""; + if (str != null) { + String reg = "\\s*|\t|\r|\n"; + Pattern p = Pattern.compile(reg); + Matcher m = p.matcher(str); + dest = m.replaceAll(""); + } + return dest; + + } + + /** + * 判断元素是否在数组内 + * + * @param substring + * @param source + * @return + */ + public static boolean isIn(String substring, String[] source) { + if (source == null || source.length == 0) { + return false; + } + for (int i = 0; i < source.length; i++) { + String aSource = source[i]; + if (aSource.equals(substring)) { + return true; + } + } + return false; + } + + /** + * 获取Map对象 + */ + public static Map getHashMap() { + return new HashMap<>(5); + } + + /** + * SET转换MAP + * + * @param + * @return + */ + public static Map setToMap(Set setobj) { + Map map = getHashMap(); + for (Iterator iterator = setobj.iterator(); iterator.hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + map.put(entry.getKey().toString(), entry.getValue() == null ? "" : entry.getValue().toString().trim()); + } + return map; + + } + + public static boolean isInnerIp(String ipAddress) { + boolean isInnerIp = false; + long ipNum = getIpNum(ipAddress); + /** + * 私有IP:A类 10.0.0.0-10.255.255.255 B类 172.16.0.0-172.31.255.255 C类 192.168.0.0-192.168.255.255 当然,还有127这个网段是环回地址 + **/ + long aBegin = getIpNum("10.0.0.0"); + long aEnd = getIpNum("10.255.255.255"); + long bBegin = getIpNum("172.16.0.0"); + long bEnd = getIpNum("172.31.255.255"); + long cBegin = getIpNum("192.168.0.0"); + long cEnd = getIpNum("192.168.255.255"); + String localIp = "127.0.0.1"; + isInnerIp = isInner(ipNum, aBegin, aEnd) || isInner(ipNum, bBegin, bEnd) || isInner(ipNum, cBegin, cEnd) || localIp.equals(ipAddress); + return isInnerIp; + } + + private static long getIpNum(String ipAddress) { + String[] ip = ipAddress.split("\\."); + long a = Integer.parseInt(ip[0]); + long b = Integer.parseInt(ip[1]); + long c = Integer.parseInt(ip[2]); + long d = Integer.parseInt(ip[3]); + + long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d; + return ipNum; + } + + private static boolean isInner(long userIp, long begin, long end) { + return (userIp >= begin) && (userIp <= end); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->helloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelName(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains(SymbolConstant.UNDERLINE)) { + // 不含下划线,仅将首字母小写 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + return name.substring(0, 1).toLowerCase() + name.substring(1).toLowerCase(); + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 处理真正的驼峰片段 + if (result.length() == 0) { + // 第一个驼峰片段,全部字母都小写 + result.append(camel.toLowerCase()); + } else { + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + } + return result.toString(); + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。 + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world,test_id->helloWorld,testId + * + * @param names + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNames(String names) { + if(names==null||"".equals(names)){ + return null; + } + StringBuffer sf = new StringBuffer(); + String[] fs = names.split(","); + for (String field : fs) { + field = camelName(field); + sf.append(field + ","); + } + String result = sf.toString(); + return result.substring(0, result.length() - 1); + } + + //update-begin--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + /** + * 将下划线大写方式命名的字符串转换为驼峰式。(首字母写) + * 如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。
+ * 例如:hello_world->HelloWorld + * + * @param name + * 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String camelNameCapFirst(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains(SymbolConstant.UNDERLINE)) { + // 不含下划线,仅将首字母小写 + return name.substring(0, 1).toUpperCase() + name.substring(1).toLowerCase(); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 其他的驼峰片段,首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + //update-end--Author:zhoujf Date:20180503 for:TASK #2500 【代码生成器】代码生成器开发一通用模板生成功能 + + /** + * 将驼峰命名转化成下划线 + * @param para + * @return + */ + public static String camelToUnderline(String para){ + int length = 3; + if(para.length() clazz = object.getClass(); + List fieldList = new ArrayList<>(); + while (clazz != null) { + fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields()))); + clazz = clazz.getSuperclass(); + } + Field[] fields = new Field[fieldList.size()]; + fieldList.toArray(fields); + return fields; + } + + /** + * 将map的key全部转成小写 + * @param list + * @return + */ + public static List> toLowerCasePageList(List> list){ + List> select = new ArrayList<>(); + for (Map row : list) { + Map resultMap = new HashMap<>(5); + Set keySet = row.keySet(); + for (String key : keySet) { + String newKey = key.toLowerCase(); + resultMap.put(newKey, row.get(key)); + } + select.add(resultMap); + } + return select; + } + + /** + * 将entityList转换成modelList + * @param fromList + * @param tClass + * @param + * @param + * @return + */ + public static List entityListToModelList(List fromList, Class tClass){ + if(fromList == null || fromList.isEmpty()){ + return null; + } + List tList = new ArrayList<>(); + for(F f : fromList){ + T t = entityToModel(f, tClass); + tList.add(t); + } + return tList; + } + + public static T entityToModel(F entity, Class modelClass) { + log.debug("entityToModel : Entity属性的值赋值到Model"); + Object model = null; + if (entity == null || modelClass ==null) { + return null; + } + + try { + model = modelClass.newInstance(); + } catch (InstantiationException e) { + log.error("entityToModel : 实例化异常", e); + } catch (IllegalAccessException e) { + log.error("entityToModel : 安全权限异常", e); + } + BeanUtils.copyProperties(entity, model); + return (T)model; + } + + /** + * 判断 list 是否为空 + * + * @param list + * @return true or false + * list == null : true + * list.size() == 0 : true + */ + public static boolean listIsEmpty(Collection list) { + return (list == null || list.size() == 0); + } + + /** + * 判断 list 是否不为空 + * + * @param list + * @return true or false + * list == null : false + * list.size() == 0 : false + */ + public static boolean listIsNotEmpty(Collection list) { + return !listIsEmpty(list); + } + + /** + * 读取静态文本内容 + * @param url + * @return + */ +// public static String readStatic(String url) { +// String json = ""; +// try { +// //换个写法,解决springboot读取jar包中文件的问题 +// InputStream stream = oConvertUtils.class.getClassLoader().getResourceAsStream(url.replace("classpath:", "")); +// json = IOUtils.toString(stream,"UTF-8"); +// } catch (IOException e) { +// log.error(e.getMessage(),e); +// } +// return json; +// } +} diff --git a/digital-common/pom.xml b/digital-common/pom.xml new file mode 100644 index 0000000..9d061b5 --- /dev/null +++ b/digital-common/pom.xml @@ -0,0 +1,25 @@ + + + + jeecg-boot-parent + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + digital-common + pom + + digital-util + digital-bean + digital-base + digital-config + + + + 8 + 8 + + + \ No newline at end of file diff --git a/digital-system/pom.xml b/digital-system/pom.xml new file mode 100644 index 0000000..719c937 --- /dev/null +++ b/digital-system/pom.xml @@ -0,0 +1,85 @@ + + + + jeecg-boot-parent + org.jeecgframework.boot + 3.2.0 + + 4.0.0 + + digital-system + + + 8 + 8 + + + + + org.springframework.boot + spring-boot-starter-actuator + + + + org.apache.shiro + shiro-spring-boot-starter + ${shiro.version} + + + + org.springframework.boot + spring-boot-starter-web + true + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + org.hibernate + hibernate-core + + + org.jeecgframework.boot + hibernate-re + + + + + com.baomidou + mybatis-plus-boot-starter + ${mybatis-plus.version} + + + org.jeecgframework.boot + digital-bean + 3.2.0 + compile + + + org.jeecgframework.boot + digital-util + 3.2.0 + compile + + + org.jeecgframework.boot + digital-base + 3.2.0 + compile + + + org.jeecgframework.boot + digital-config + 3.2.0 + compile + + + com.squareup.okhttp3 + okhttp + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/controller/SystemAPIController.java b/digital-system/src/main/java/digital/system/jeecg/controller/SystemAPIController.java new file mode 100644 index 0000000..6662c37 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/controller/SystemAPIController.java @@ -0,0 +1,697 @@ +package digital.system.jeecg.controller; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import digital.base.vo.LoginUser; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.bean.jeecg.dto.OnlineAuthDTO; +import digital.bean.jeecg.dto.message.*; +import digital.bean.jeecg.vo.*; +import digital.system.jeecg.system.service.ISysUserService; +import digital.system.jeecg.system.service.impl.SysBaseApiImpl; +import digital.util.util.SysUserCacheInfo; + +import java.util.List; +import java.util.Map; +import java.util.Set; + + +/** + * 服务化 system模块 对外接口请求类 + * + * @author: smcp + */ +@Slf4j +@RestController +@RequestMapping("/sys/api") +public class SystemAPIController { + + @Autowired + private SysBaseApiImpl sysBaseApi; + @Autowired + private ISysUserService sysUserService; + + + /** + * 发送系统消息 + * + * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息 + */ + @PostMapping("/sendSysAnnouncement") + public void sendSysAnnouncement(@RequestBody MessageDTO message) { + sysBaseApi.sendSysAnnouncement(message); + } + + /** + * 发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendBusAnnouncement") + public void sendBusAnnouncement(@RequestBody BusMessageDTO message) { + sysBaseApi.sendBusAnnouncement(message); + } + + /** + * 通过模板发送消息 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendTemplateAnnouncement") + public void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message) { + sysBaseApi.sendTemplateAnnouncement(message); + } + + /** + * 通过模板发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sendBusTemplateAnnouncement") + public void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message) { + sysBaseApi.sendBusTemplateAnnouncement(message); + } + + /** + * 通过消息中心模板,生成推送内容 + * + * @param templateDTO 使用构造器赋值参数 + * @return + */ + @PostMapping("/parseTemplateByCode") + public String parseTemplateByCode(@RequestBody TemplateDTO templateDTO) { + return sysBaseApi.parseTemplateByCode(templateDTO); + } + + /** + * 根据业务类型busType及业务busId修改消息已读 + */ + @GetMapping("/updateSysAnnounReadFlag") + public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId") String busId) { + sysBaseApi.updateSysAnnounReadFlag(busType, busId); + } + + /** + * 根据用户账号查询用户信息 + * + * @param username + * @return + */ + @GetMapping("/getUserByName") + public LoginUser getUserByName(@RequestParam("username") String username) { + return sysBaseApi.getUserByName(username); + } + + /** + * 根据用户id查询用户信息 + * + * @param id + * @return + */ + @GetMapping("/getUserById") + LoginUser getUserById(@RequestParam("id") String id) { + return sysBaseApi.getUserById(id); + } + + /** + * 通过用户账号查询角色集合 + * + * @param username + * @return + */ + @GetMapping("/getRolesByUsername") + List getRolesByUsername(@RequestParam("username") String username) { + return sysBaseApi.getRolesByUsername(username); + } + + /** + * 通过用户账号查询部门集合 + * + * @param username + * @return 部门 id + */ + @GetMapping("/getDepartIdsByUsername") + List getDepartIdsByUsername(@RequestParam("username") String username) { + return sysBaseApi.getDepartIdsByUsername(username); + } + + /** + * 通过用户账号查询部门 name + * + * @param username + * @return 部门 name + */ + @GetMapping("/getDepartNamesByUsername") + List getDepartNamesByUsername(@RequestParam("username") String username) { + return sysBaseApi.getDepartNamesByUsername(username); + } + + + /** + * 获取数据字典 + * + * @param code + * @return + */ + @GetMapping("/queryDictItemsByCode") + List queryDictItemsByCode(@RequestParam("code") String code) { + return sysBaseApi.queryDictItemsByCode(code); + } + + /** + * 获取有效的数据字典 + * + * @param code + * @return + */ + @GetMapping("/queryEnableDictItemsByCode") + List queryEnableDictItemsByCode(@RequestParam("code") String code) { + return sysBaseApi.queryEnableDictItemsByCode(code); + } + + + /** + * 查询所有的父级字典,按照create_time排序 + */ + @GetMapping("/queryAllDict") + List queryAllDict() { +// try{ +// //睡10秒,gateway网关5秒超时,会触发熔断降级操作 +// Thread.sleep(10000); +// }catch (Exception e){ +// e.printStackTrace(); +// } + + log.info("--我是jeecg-system服务节点,微服务接口queryAllDict被调用--"); + return sysBaseApi.queryAllDict(); + } + + /** + * 查询所有分类字典 + * + * @return + */ + @GetMapping("/queryAllSysCategory") + List queryAllSysCategory() { + return sysBaseApi.queryAllSysCategory(); + } + + + /** + * 查询所有部门 作为字典信息 id -->value,departName -->text + * + * @return + */ + @GetMapping("/queryAllDepartBackDictModel") + List queryAllDepartBackDictModel() { + return sysBaseApi.queryAllDepartBackDictModel(); + } + + /** + * 获取所有角色 带参 + * roleIds 默认选中角色 + * + * @return + */ + @GetMapping("/queryAllRole") + public List queryAllRole(@RequestParam(name = "roleIds", required = false) String[] roleIds) { + if (roleIds == null || roleIds.length == 0) { + return sysBaseApi.queryAllRole(); + } else { + return sysBaseApi.queryAllRole(roleIds); + } + } + + /** + * 通过用户账号查询角色Id集合 + * + * @param username + * @return + */ + @GetMapping("/getRoleIdsByUsername") + public List getRoleIdsByUsername(@RequestParam("username") String username) { + return sysBaseApi.getRoleIdsByUsername(username); + } + + /** + * 通过部门编号查询部门id + * + * @param orgCode + * @return + */ + @GetMapping("/getDepartIdsByOrgCode") + public String getDepartIdsByOrgCode(@RequestParam("orgCode") String orgCode) { + return sysBaseApi.getDepartIdsByOrgCode(orgCode); + } + + /** + * 查询所有部门 + * + * @return + */ + @GetMapping("/getAllSysDepart") + public List getAllSysDepart() { + return sysBaseApi.getAllSysDepart(); + } + + /** + * 根据 id 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceId + * @return + */ + @GetMapping("/getDynamicDbSourceById") + DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId") String dbSourceId) { + return sysBaseApi.getDynamicDbSourceById(dbSourceId); + } + + + /** + * 根据部门Id获取部门负责人 + * + * @param deptId + * @return + */ + @GetMapping("/getDeptHeadByDepId") + public List getDeptHeadByDepId(@RequestParam("deptId") String deptId) { + return sysBaseApi.getDeptHeadByDepId(deptId); + } + + /** + * 查找父级部门 + * + * @param departId + * @return + */ + @GetMapping("/getParentDepartId") + public DictModel getParentDepartId(@RequestParam("departId") String departId) { + return sysBaseApi.getParentDepartId(departId); + } + + /** + * 根据 code 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceCode + * @return + */ + @GetMapping("/getDynamicDbSourceByCode") + public DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode) { + return sysBaseApi.getDynamicDbSourceByCode(dbSourceCode); + } + + /** + * 给指定用户发消息 + * + * @param userIds + * @param cmd + */ + @GetMapping("/sendWebSocketMsg") + public void sendWebSocketMsg(String[] userIds, String cmd) { + sysBaseApi.sendWebSocketMsg(userIds, cmd); + } + + + /** + * 根据id获取所有参与用户 + * userIds + * + * @return + */ + @GetMapping("/queryAllUserByIds") + public List queryAllUserByIds(@RequestParam("userIds") String[] userIds) { + return sysBaseApi.queryAllUserByIds(userIds); + } + + /** + * 查询所有用户 返回ComboModel + * + * @return + */ + @GetMapping("/queryAllUserBackCombo") + public List queryAllUserBackCombo() { + return sysBaseApi.queryAllUserBackCombo(); + } + + /** + * 分页查询用户 返回JSONObject + * + * @return + */ + @GetMapping("/queryAllUser") + public JSONObject queryAllUser(@RequestParam(name = "userIds", required = false) String userIds, @RequestParam(name = "pageNo", required = false) Integer pageNo, @RequestParam(name = "pageSize", required = false) int pageSize) { + return sysBaseApi.queryAllUser(userIds, pageNo, pageSize); + } + + + /** + * 将会议签到信息推动到预览 + * userIds + * + * @param userId + * @return + */ + @GetMapping("/meetingSignWebsocket") + public void meetingSignWebsocket(@RequestParam("userId") String userId) { + sysBaseApi.meetingSignWebsocket(userId); + } + + /** + * 根据name获取所有参与用户 + * userNames + * + * @return + */ + @GetMapping("/queryUserByNames") + public List queryUserByNames(@RequestParam("userNames") String[] userNames) { + return sysBaseApi.queryUserByNames(userNames); + } + + /** + * 获取用户的角色集合 + * + * @param username + * @return + */ + @GetMapping("/getUserRoleSet") + public Set getUserRoleSet(@RequestParam("username") String username) { + return sysBaseApi.getUserRoleSet(username); + } + + /** + * 获取用户的权限集合 + * + * @param username + * @return + */ + @GetMapping("/getUserPermissionSet") + public Set getUserPermissionSet(@RequestParam("username") String username) { + return sysBaseApi.getUserPermissionSet(username); + } + + //----- + + /** + * 判断是否有online访问的权限 + * + * @param onlineAuthDTO + * @return + */ + @PostMapping("/hasOnlineAuth") + public boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO) { + return sysBaseApi.hasOnlineAuth(onlineAuthDTO); + } + + /** + * 查询用户角色信息 + * + * @param username + * @return + */ + @GetMapping("/queryUserRoles") + public Set queryUserRoles(@RequestParam("username") String username) { + return sysUserService.getUserRolesSet(username); + } + + + /** + * 查询用户权限信息 + * + * @param username + * @return + */ + @GetMapping("/queryUserAuths") + public Set queryUserAuths(@RequestParam("username") String username) { + return sysUserService.getUserPermissionsSet(username); + } + + /** + * 通过部门id获取部门全部信息 + */ + @GetMapping("/selectAllById") + public SysDepartModel selectAllById(@RequestParam("id") String id) { + return sysBaseApi.selectAllById(id); + } + + /** + * 根据用户id查询用户所属公司下所有用户ids + * + * @param userId + * @return + */ + @GetMapping("/queryDeptUsersByUserId") + public List queryDeptUsersByUserId(@RequestParam("userId") String userId) { + return sysBaseApi.queryDeptUsersByUserId(userId); + } + + + /** + * 查询数据权限 + * + * @return + */ + @GetMapping("/queryPermissionDataRule") + public List queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath") String requestPath, @RequestParam("username") String username) { + return sysBaseApi.queryPermissionDataRule(component, requestPath, username); + } + + /** + * 查询用户信息 + * + * @param username + * @return + */ + @GetMapping("/getCacheUser") + public SysUserCacheInfo getCacheUser(@RequestParam("username") String username) { + return sysBaseApi.getCacheUser(username); + } + + /** + * 普通字典的翻译 + * + * @param code + * @param key + * @return + */ + @GetMapping("/translateDict") + public String translateDict(@RequestParam("code") String code, @RequestParam("key") String key) { + return sysBaseApi.translateDict(code, key); + } + + + /** + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息 + * + * @param usernames + * @return + */ + @RequestMapping("/queryUsersByUsernames") + List queryUsersByUsernames(@RequestParam("usernames") String usernames) { + return this.sysBaseApi.queryUsersByUsernames(usernames); + } + + /** + * 37根据多个用户id(逗号分隔),查询返回多个用户信息 + * + * @param ids + * @return + */ + @RequestMapping("/queryUsersByIds") + List queryUsersByIds(@RequestParam("ids") String ids) { + return this.sysBaseApi.queryUsersByIds(ids); + } + + /** + * 38根据多个部门编码(逗号分隔),查询返回多个部门信息 + * + * @param orgCodes + * @return + */ + @GetMapping("/queryDepartsByOrgcodes") + List queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes) { + return this.sysBaseApi.queryDepartsByOrgcodes(orgCodes); + } + + /** + * 39根据多个部门ID(逗号分隔),查询返回多个部门信息 + * + * @param ids + * @return + */ + @GetMapping("/queryDepartsByIds") + List queryDepartsByIds(@RequestParam("ids") String ids) { + return this.sysBaseApi.queryDepartsByIds(ids); + } + + /** + * 40发送邮件消息 + * + * @param email + * @param title + * @param content + */ +// @GetMapping("/sendEmailMsg") +// public void sendEmailMsg(@RequestParam("email") String email, @RequestParam("title") String title, @RequestParam("content") String content) { +// this.sysBaseApi.sendEmailMsg(email, title, content); +// } + + ; + + /** + * 41 获取公司下级部门和公司下所有用户信息 + * + * @param orgCode + */ + @GetMapping("/getDeptUserByOrgCode") + List getDeptUserByOrgCode(@RequestParam("orgCode") String orgCode) { + return this.sysBaseApi.getDeptUserByOrgCode(orgCode); + } + + /** + * 查询分类字典翻译 + * + * @param ids 分类字典表id + * @return + */ + @GetMapping("/loadCategoryDictItem") + public List loadCategoryDictItem(@RequestParam("ids") String ids) { + return sysBaseApi.loadCategoryDictItem(ids); + } + + /** + * 根据字典code加载字典text + * + * @param dictCode 顺序:tableName,text,code + * @param keys 要查询的key + * @return + */ + @GetMapping("/loadDictItem") + public List loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys) { + return sysBaseApi.loadDictItem(dictCode, keys); + } + + /** + * 根据字典code查询字典项 + * + * @param dictCode 顺序:tableName,text,code + * @param dictCode 要查询的key + * @return + */ + @GetMapping("/getDictItems") + public List getDictItems(@RequestParam("dictCode") String dictCode) { + return sysBaseApi.getDictItems(dictCode); + } + + /** + * 根据多个字典code查询多个字典项 + * + * @param dictCodeList + * @return key = dictCode ; value=对应的字典项 + */ + @RequestMapping("/getManyDictItems") + public Map> getManyDictItems(@RequestParam("dictCodeList") List dictCodeList) { + return sysBaseApi.getManyDictItems(dictCodeList); + } + + /** + * 【下拉搜索】 + * 大数据量的字典表 走异步加载,即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword 过滤关键字 + * @return + */ + @GetMapping("/loadDictItemByKeyword") + public List loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize) { + return sysBaseApi.loadDictItemByKeyword(dictCode, keyword, pageSize); + } + + /** + * 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割 + * + * @param dictCodes + * @param keys + * @return + */ + @GetMapping("/translateManyDict") + public Map> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys) { + return this.sysBaseApi.translateManyDict(dictCodes, keys); + } + + + /** + * 获取表数据字典 【接口签名验证】 + * + * @param table + * @param text + * @param code + * @return + */ + @GetMapping("/queryTableDictItemsByCode") + List queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code) { + return sysBaseApi.queryTableDictItemsByCode(table, text, code); + } + + /** + * 查询表字典 支持过滤数据 【接口签名验证】 + * + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @GetMapping("/queryFilterTableDictInfo") + List queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql) { + return sysBaseApi.queryFilterTableDictInfo(table, text, code, filterSql); + } + + /** + * 【接口签名验证】 + * 查询指定table的 text code 获取字典,包含text和value + * + * @param table + * @param text + * @param code + * @param keyArray + * @return + */ + @Deprecated + @GetMapping("/queryTableDictByKeys") + public List queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray) { + return sysBaseApi.queryTableDictByKeys(table, text, code, keyArray); + } + + + /** + * 字典表的 翻译【接口签名验证】 + * + * @param table + * @param text + * @param code + * @param key + * @return + */ + @GetMapping("/translateDictFromTable") + public String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key) { + return sysBaseApi.translateDictFromTable(table, text, code, key); + } + + + /** + * 【接口签名验证】 + * 49 字典表的 翻译,可批量 + * + * @param table + * @param text + * @param code + * @param keys 多个用逗号分割 + * @return + */ + @GetMapping("/translateDictFromTableByKeys") + public List translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys) { + return this.sysBaseApi.translateDictFromTableByKeys(table, text, code, keys); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/CommonAPI.java b/digital-system/src/main/java/digital/system/jeecg/group/CommonAPI.java new file mode 100644 index 0000000..40df6c3 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/CommonAPI.java @@ -0,0 +1,134 @@ +package digital.system.jeecg.group; + +import digital.base.vo.LoginUser; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.bean.jeecg.vo.DictModel; +import digital.bean.jeecg.vo.DynamicDataSourceModel; +import digital.util.util.SysUserCacheInfo; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 通用api + * @author: smcp + */ +public interface CommonAPI { + + /** + * 1查询用户角色信息 + * @param username + * @return + */ + Set queryUserRoles(String username); + + + /** + * 2查询用户权限信息 + * @param username + * @return + */ + Set queryUserAuths(String username); + + /** + * 3根据 id 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceId + * @return + */ + DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId); + + /** + * 4根据 code 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceCode + * @return + */ + DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode); + + /** + * 5根据用户账号查询用户信息 + * @param username + * @return + */ + public LoginUser getUserByName(String username); + + + /** + * 6字典表的 翻译 + * @param table + * @param text + * @param code + * @param key + * @return + */ + String translateDictFromTable(String table, String text, String code, String key); + + /** + * 7普通字典的翻译 + * @param code + * @param key + * @return + */ + String translateDict(String code, String key); + + /** + * 8查询数据权限 + * @param component 组件 + * @param username 用户名 + * @param requestPath 前段请求地址 + * @return + */ + List queryPermissionDataRule(String component, String requestPath, String username); + + + /** + * 9查询用户信息 + * @param username + * @return + */ + SysUserCacheInfo getCacheUser(String username); + + /** + * 10获取数据字典 + * @param code + * @return + */ + public List queryDictItemsByCode(String code); + + /** + * 获取有效的数据字典项 + * @param code + * @return + */ + public List queryEnableDictItemsByCode(String code); + + /** + * 13获取表数据字典 + * @param table + * @param text + * @param code + * @return + */ + List queryTableDictItemsByCode(String table, String text, String code); + + /** + * 14 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割 + * @param dictCodes 例如:user_status,sex + * @param keys 例如:1,2,0 + * @return + */ + Map> translateManyDict(String dictCodes, String keys); + + /** + * 15 字典表的 翻译,可批量 + * @param table + * @param text + * @param code + * @param keys 多个用逗号分割 + * @return + */ + List translateDictFromTableByKeys(String table, String text, String code, String keys); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/api/ISysBaseAPI.java b/digital-system/src/main/java/digital/system/jeecg/group/api/ISysBaseAPI.java new file mode 100644 index 0000000..791b6d1 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/api/ISysBaseAPI.java @@ -0,0 +1,592 @@ +package digital.system.jeecg.group.api; + +import com.alibaba.fastjson.JSONObject; +import digital.system.jeecg.group.CommonAPI; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; +import digital.base.vo.LoginUser; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.bean.jeecg.dto.OnlineAuthDTO; +import digital.bean.jeecg.dto.message.*; +import digital.bean.jeecg.vo.*; +import digital.util.util.SysUserCacheInfo; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 1、cloud接口数量43 local:35 common:9 额外一个特殊queryAllRole一个当两个用 + * - 相比较local版jeecg. + * - 去掉了一些方法:addLog、getDatabaseType、queryAllDepart、queryAllUser(Wrapper wrapper)、queryAllUser(String[] userIds, int pageNo, int pageSize) + * - 修改了一些方法:createLog、sendSysAnnouncement(只保留了一个,其余全部干掉) + * 2、@ConditionalOnMissingClass("org.jeecg.modules.system.service.impl.SysBaseApiImpl")=> 有实现类的时候,不实例化Feign接口 + * + * @author: smcp + */ +@Component +//@FeignClient(contextId = "sysBaseRemoteApi", value = ServiceNameConstants.SERVICE_SYSTEM, fallbackFactory = SysBaseAPIFallbackFactory.class) +//@ConditionalOnMissingClass("digital.system.modules.system.service.impl.SysBaseApiImpl") +public interface ISysBaseAPI extends CommonAPI { + + /** + * 1发送系统消息 + * + * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息 + */ + @PostMapping("/sys/api/sendSysAnnouncement") + void sendSysAnnouncement(@RequestBody MessageDTO message); + + /** + * 2发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sys/api/sendBusAnnouncement") + void sendBusAnnouncement(@RequestBody BusMessageDTO message); + + /** + * 3通过模板发送消息 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sys/api/sendTemplateAnnouncement") + void sendTemplateAnnouncement(@RequestBody TemplateMessageDTO message); + + /** + * 4通过模板发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + @PostMapping("/sys/api/sendBusTemplateAnnouncement") + void sendBusTemplateAnnouncement(@RequestBody BusTemplateMessageDTO message); + + /** + * 5通过消息中心模板,生成推送内容 + * + * @param templateDTO 使用构造器赋值参数 + * @return + */ + @PostMapping("/sys/api/parseTemplateByCode") + String parseTemplateByCode(@RequestBody TemplateDTO templateDTO); + + /** + * 6根据用户id查询用户信息 + * + * @param id + * @return + */ + @GetMapping("/sys/api/getUserById") + LoginUser getUserById(@RequestParam("id") String id); + + /** + * 7通过用户账号查询角色集合 + * + * @param username + * @return + */ + @GetMapping("/sys/api/getRolesByUsername") + List getRolesByUsername(@RequestParam("username") String username); + + /** + * 8通过用户账号查询部门集合 + * + * @param username + * @return 部门 id + */ + @GetMapping("/sys/api/getDepartIdsByUsername") + List getDepartIdsByUsername(@RequestParam("username") String username); + + /** + * 9通过用户账号查询部门 name + * + * @param username + * @return 部门 name + */ + @GetMapping("/sys/api/getDepartNamesByUsername") + List getDepartNamesByUsername(@RequestParam("username") String username); + + /** + * 10获取数据字典 + * + * @param code + * @return + */ + @Override + @GetMapping("/sys/api/queryDictItemsByCode") + List queryDictItemsByCode(@RequestParam("code") String code); + + /** + * 获取有效的数据字典项 + * + * @param code + * @return + */ + @Override + @GetMapping("/sys/api/queryEnableDictItemsByCode") + public List queryEnableDictItemsByCode(@RequestParam("code") String code); + + /** + * 11查询所有的父级字典,按照create_time排序 + * + * @return List 字典值集合 + */ + @GetMapping("/sys/api/queryAllDict") + List queryAllDict(); + + /** + * 12查询所有分类字典 + * + * @return + */ + @GetMapping("/sys/api/queryAllSysCategory") + List queryAllSysCategory(); + + /** + * 13获取表数据字典 + * + * @param table + * @param text + * @param code + * @return + */ + @Override + @GetMapping("/sys/api/queryTableDictItemsByCode") + List queryTableDictItemsByCode(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code); + + /** + * 14查询所有部门 作为字典信息 id -->value,departName -->text + * + * @return + */ + @GetMapping("/sys/api/queryAllDepartBackDictModel") + List queryAllDepartBackDictModel(); + + /** + * 15根据业务类型 busType 及业务 busId 修改消息已读 + * + * @param busType 业务类型 + * @param busId 业务id + */ + @GetMapping("/sys/api/updateSysAnnounReadFlag") + public void updateSysAnnounReadFlag(@RequestParam("busType") String busType, @RequestParam("busId") String busId); + + /** + * 16查询表字典 支持过滤数据 + * + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @GetMapping("/sys/api/queryFilterTableDictInfo") + List queryFilterTableDictInfo(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("filterSql") String filterSql); + + /** + * 17查询指定table的 text code 获取字典,包含text和value + * + * @param table + * @param text + * @param code + * @param keyArray + * @return + */ + @Deprecated + @GetMapping("/sys/api/queryTableDictByKeys") + public List queryTableDictByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keyArray") String[] keyArray); + + /** + * 18查询所有用户 返回ComboModel + * + * @return + */ + @GetMapping("/sys/api/queryAllUserBackCombo") + public List queryAllUserBackCombo(); + + /** + * 19分页查询用户 返回JSONObject + * + * @param userIds 多个用户id + * @param pageNo 当前页数 + * @param pageSize 每页条数 + * @return + */ + @GetMapping("/sys/api/queryAllUser") + public JSONObject queryAllUser(@RequestParam(name = "userIds", required = false) String userIds, @RequestParam(name = "pageNo", required = false) Integer pageNo, @RequestParam(name = "pageSize", required = false) int pageSize); + + + /** + * 20获取所有角色 带参 + * + * @param roleIds 默认选中角色 + * @return + */ + @GetMapping("/sys/api/queryAllRole") + public List queryAllRole(@RequestParam(name = "roleIds", required = false) String[] roleIds); + + /** + * 21通过用户账号查询角色Id集合 + * + * @param username + * @return + */ + @GetMapping("/sys/api/getRoleIdsByUsername") + public List getRoleIdsByUsername(@RequestParam("username") String username); + + /** + * 22通过部门编号查询部门id + * + * @param orgCode + * @return + */ + @GetMapping("/sys/api/getDepartIdsByOrgCode") + public String getDepartIdsByOrgCode(@RequestParam("orgCode") String orgCode); + + /** + * 23查询所有部门 + * + * @return + */ + @GetMapping("/sys/api/getAllSysDepart") + public List getAllSysDepart(); + + /** + * 24查找父级部门 + * + * @param departId + * @return + */ + @GetMapping("/sys/api/getParentDepartId") + DictModel getParentDepartId(@RequestParam("departId") String departId); + + /** + * 25根据部门Id获取部门负责人 + * + * @param deptId + * @return + */ + @GetMapping("/sys/api/getDeptHeadByDepId") + public List getDeptHeadByDepId(@RequestParam("deptId") String deptId); + + /** + * 26给指定用户发消息 + * + * @param userIds + * @param cmd + */ + @GetMapping("/sys/api/sendWebSocketMsg") + public void sendWebSocketMsg(@RequestParam("userIds") String[] userIds, @RequestParam("cmd") String cmd); + + /** + * 27根据id获取所有参与用户 + * + * @param userIds 多个用户id + * @return + */ + @GetMapping("/sys/api/queryAllUserByIds") + public List queryAllUserByIds(@RequestParam("userIds") String[] userIds); + + /** + * 28将会议签到信息推动到预览 + * userIds + * + * @param userId + * @return + */ + @GetMapping("/sys/api/meetingSignWebsocket") + void meetingSignWebsocket(@RequestParam("userId") String userId); + + /** + * 29根据name获取所有参与用户 + * + * @param userNames 多个用户账号 + * @return + */ + @GetMapping("/sys/api/queryUserByNames") + List queryUserByNames(@RequestParam("userNames") String[] userNames); + + + /** + * 30获取用户的角色集合 + * + * @param username + * @return + */ + @GetMapping("/sys/api/getUserRoleSet") + Set getUserRoleSet(@RequestParam("username") String username); + + /** + * 31获取用户的权限集合 + * + * @param username + * @return + */ + @GetMapping("/sys/api/getUserPermissionSet") + Set getUserPermissionSet(@RequestParam("username") String username); + + /** + * 32判断是否有online访问的权限 + * + * @param onlineAuthDTO + * @return + */ + @PostMapping("/sys/api/hasOnlineAuth") + boolean hasOnlineAuth(@RequestBody OnlineAuthDTO onlineAuthDTO); + + /** + * 33通过部门id获取部门全部信息 + * + * @param id 部门id + * @return SysDepartModel 部门信息 + */ + @GetMapping("/sys/api/selectAllById") + SysDepartModel selectAllById(@RequestParam("id") String id); + + /** + * 34根据用户id查询用户所属公司下所有用户ids + * + * @param userId + * @return + */ + @GetMapping("/sys/api/queryDeptUsersByUserId") + List queryDeptUsersByUserId(@RequestParam("userId") String userId); + + + //--- + + /** + * 35查询用户角色信息 + * + * @param username + * @return + */ + @Override + @GetMapping("/sys/api/queryUserRoles") + Set queryUserRoles(@RequestParam("username") String username); + + /** + * 36查询用户权限信息 + * + * @param username + * @return + */ + @Override + @GetMapping("/sys/api/queryUserAuths") + Set queryUserAuths(@RequestParam("username") String username); + + /** + * 37根据 id 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceId + * @return + */ + @Override + @GetMapping("/sys/api/getDynamicDbSourceById") + DynamicDataSourceModel getDynamicDbSourceById(@RequestParam("dbSourceId") String dbSourceId); + + /** + * 38根据 code 查询数据库中存储的 DynamicDataSourceModel + * + * @param dbSourceCode + * @return + */ + @Override + @GetMapping("/sys/api/getDynamicDbSourceByCode") + DynamicDataSourceModel getDynamicDbSourceByCode(@RequestParam("dbSourceCode") String dbSourceCode); + + /** + * 39根据用户账号查询用户信息 CommonAPI中定义 + * + * @param username + * @return LoginUser 用户信息 + */ + @Override + @GetMapping("/sys/api/getUserByName") + LoginUser getUserByName(@RequestParam("username") String username); + + /** + * 40字典表的 翻译 + * + * @param table + * @param text + * @param code + * @param key + * @return + */ + @Override + @GetMapping("/sys/api/translateDictFromTable") + String translateDictFromTable(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("key") String key); + + /** + * 41普通字典的翻译 + * + * @param code + * @param key + * @return + */ + @Override + @GetMapping("/sys/api/translateDict") + String translateDict(@RequestParam("code") String code, @RequestParam("key") String key); + + /** + * 42查询数据权限 + * + * @param component + * @param requestPath + * @param username 用户姓名 + * @return + */ + @Override + @GetMapping("/sys/api/queryPermissionDataRule") + List queryPermissionDataRule(@RequestParam("component") String component, @RequestParam("requestPath") String requestPath, @RequestParam("username") String username); + + /** + * 43查询用户信息 + * + * @param username + * @return + */ + @Override + @GetMapping("/sys/api/getCacheUser") + SysUserCacheInfo getCacheUser(@RequestParam("username") String username); + + /** + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息 + * + * @param usernames + * @return + */ + @GetMapping("/sys/api/queryUsersByUsernames") + List queryUsersByUsernames(@RequestParam("usernames") String usernames); + + /** + * 37根据多个用户ID(逗号分隔),查询返回多个用户信息 + * + * @param ids + * @return + */ + @RequestMapping("/sys/api/queryUsersByIds") + List queryUsersByIds(@RequestParam("ids") String ids); + + /** + * 38根据多个部门编码(逗号分隔),查询返回多个部门信息 + * + * @param orgCodes + * @return + */ + @RequestMapping("/sys/api/queryDepartsByOrgcodes") + List queryDepartsByOrgcodes(@RequestParam("orgCodes") String orgCodes); + + /** + * 39根据多个部门编码(逗号分隔),查询返回多个部门信息 + * + * @param ids + * @return + */ + @GetMapping("/sys/api/queryDepartsByOrgIds") + List queryDepartsByOrgIds(@RequestParam("ids") String ids); + + /** + * 40发送邮件消息 + * + * @param email + * @param title + * @param content + */ + @GetMapping("/sys/api/sendEmailMsg") + void sendEmailMsg(@RequestParam("email") String email, @RequestParam("title") String title, @RequestParam("content") String content); + + /** + * 41 获取公司下级部门和公司下所有用户id + * + * @param orgCode 部门编号 + * @return List + */ + @GetMapping("/sys/api/getDeptUserByOrgCode") + List getDeptUserByOrgCode(@RequestParam("orgCode") String orgCode); + + /** + * 42 查询分类字典翻译 + * + * @param ids 多个分类字典id + * @return List + */ + @GetMapping("/sys/api/loadCategoryDictItem") + List loadCategoryDictItem(@RequestParam("ids") String ids); + + /** + * 43 根据字典code加载字典text + * + * @param dictCode 顺序:tableName,text,code + * @param keys 要查询的key + * @return + */ + @GetMapping("/sys/api/loadDictItem") + List loadDictItem(@RequestParam("dictCode") String dictCode, @RequestParam("keys") String keys); + + /** + * 44 根据字典code查询字典项 + * + * @param dictCode 顺序:tableName,text,code + * @param dictCode 要查询的key + * @return + */ + @GetMapping("/sys/api/getDictItems") + List getDictItems(@RequestParam("dictCode") String dictCode); + + /** + * 45 根据多个字典code查询多个字典项 + * + * @param dictCodeList + * @return key = dictCode ; value=对应的字典项 + */ + @RequestMapping("/sys/api/getManyDictItems") + Map> getManyDictItems(@RequestParam("dictCodeList") List dictCodeList); + + /** + * 46 【JSearchSelectTag下拉搜索组件专用接口】 + * 大数据量的字典表 走异步加载 即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword 过滤关键字 + * @param pageSize 每页条数 + * @return + */ + @GetMapping("/sys/api/loadDictItemByKeyword") + List loadDictItemByKeyword(@RequestParam("dictCode") String dictCode, @RequestParam("keyword") String keyword, @RequestParam(value = "pageSize", required = false) Integer pageSize); + + /** + * 47 根据多个部门id(逗号分隔),查询返回多个部门信息 + * + * @param ids + * @return + */ + @GetMapping("/sys/api/queryDepartsByIds") + List queryDepartsByIds(@RequestParam("ids") String ids); + + /** + * 48 普通字典的翻译,根据多个dictCode和多条数据,多个以逗号分割 + * + * @param dictCodes + * @param keys + * @return + */ + @Override + @GetMapping("/sys/api/translateManyDict") + Map> translateManyDict(@RequestParam("dictCodes") String dictCodes, @RequestParam("keys") String keys); + + /** + * 49 字典表的 翻译,可批量 + * + * @param table + * @param text + * @param code + * @param keys 多个用逗号分割 + * @return + */ + @Override + @GetMapping("/sys/api/translateDictFromTableByKeys") + List translateDictFromTableByKeys(@RequestParam("table") String table, @RequestParam("text") String text, @RequestParam("code") String code, @RequestParam("keys") String keys); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/api/factory/SysBaseAPIFallbackFactory.java b/digital-system/src/main/java/digital/system/jeecg/group/api/factory/SysBaseAPIFallbackFactory.java new file mode 100644 index 0000000..f387e89 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/api/factory/SysBaseAPIFallbackFactory.java @@ -0,0 +1,21 @@ +package digital.system.jeecg.group.api.factory; + +import digital.system.jeecg.group.api.ISysBaseAPI; +import digital.system.jeecg.group.api.fallback.SysBaseAPIFallback; +import org.springframework.cloud.openfeign.FallbackFactory; +import org.springframework.stereotype.Component; + +/** + * @Description: SysBaseAPIFallbackFactory + * @author: smcp + */ +@Component +public class SysBaseAPIFallbackFactory implements FallbackFactory { + + @Override + public ISysBaseAPI create(Throwable throwable) { + SysBaseAPIFallback fallback = new SysBaseAPIFallback(); + fallback.setCause(throwable); + return fallback; + } +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/group/api/fallback/SysBaseAPIFallback.java b/digital-system/src/main/java/digital/system/jeecg/group/api/fallback/SysBaseAPIFallback.java new file mode 100644 index 0000000..df971c4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/api/fallback/SysBaseAPIFallback.java @@ -0,0 +1,324 @@ +package digital.system.jeecg.group.api.fallback; + +import com.alibaba.fastjson.JSONObject; +import digital.system.jeecg.group.api.ISysBaseAPI; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import digital.base.vo.LoginUser; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.bean.jeecg.dto.OnlineAuthDTO; +import digital.bean.jeecg.dto.message.*; +import digital.bean.jeecg.vo.*; +import digital.util.util.SysUserCacheInfo; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 进入fallback的方法 检查是否token未设置 + * + * @author: smcp + */ +@Slf4j +public class SysBaseAPIFallback implements ISysBaseAPI { + + @Setter + private Throwable cause; + + @Override + public void sendSysAnnouncement(MessageDTO message) { + log.error("发送消息失败 {}", cause); + } + + @Override + public void sendBusAnnouncement(BusMessageDTO message) { + log.error("发送消息失败 {}", cause); + } + + @Override + public void sendTemplateAnnouncement(TemplateMessageDTO message) { + log.error("发送消息失败 {}", cause); + } + + @Override + public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) { + log.error("发送消息失败 {}", cause); + } + + @Override + public String parseTemplateByCode(TemplateDTO templateDTO) { + log.error("通过模板获取消息内容失败 {}", cause); + return null; + } + + @Override + public LoginUser getUserById(String id) { + return null; + } + + @Override + public List getRolesByUsername(String username) { + return null; + } + + @Override + public List getDepartIdsByUsername(String username) { + return null; + } + + @Override + public List getDepartNamesByUsername(String username) { + return null; + } + + @Override + public List queryDictItemsByCode(String code) { + return null; + } + + @Override + public List queryEnableDictItemsByCode(String code) { + return null; + } + + @Override + public List queryAllDict() { + log.error("fegin接口queryAllDict失败:" + cause.getMessage(), cause); + return null; + } + + @Override + public List queryAllSysCategory() { + return null; + } + + @Override + public List queryTableDictItemsByCode(String table, String text, String code) { + return null; + } + + @Override + public List queryAllDepartBackDictModel() { + return null; + } + + @Override + public void updateSysAnnounReadFlag(String busType, String busId) { + + } + + @Override + public List queryFilterTableDictInfo(String table, String text, String code, String filterSql) { + return null; + } + + @Override + public List queryTableDictByKeys(String table, String text, String code, String[] keyArray) { + log.error("queryTableDictByKeys查询失败 {}", cause); + return null; + } + + @Override + public List queryAllUserBackCombo() { + return null; + } + + @Override + public JSONObject queryAllUser(String userIds, Integer pageNo, int pageSize) { + return null; + } + + @Override + public List queryAllRole(String[] roleIds) { + log.error("获取角色信息失败 {}", cause); + return null; + } + + @Override + public List getRoleIdsByUsername(String username) { + return null; + } + + @Override + public String getDepartIdsByOrgCode(String orgCode) { + return null; + } + + @Override + public List getAllSysDepart() { + return null; + } + + @Override + public DictModel getParentDepartId(String departId) { + return null; + } + + @Override + public List getDeptHeadByDepId(String deptId) { + return null; + } + + @Override + public void sendWebSocketMsg(String[] userIds, String cmd) { + + } + + @Override + public List queryAllUserByIds(String[] userIds) { + return null; + } + + @Override + public void meetingSignWebsocket(String userId) { + + } + + @Override + public List queryUserByNames(String[] userNames) { + return null; + } + + @Override + public Set getUserRoleSet(String username) { + return null; + } + + @Override + public Set getUserPermissionSet(String username) { + return null; + } + + @Override + public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) { + return false; + } + + @Override + public SysDepartModel selectAllById(String id) { + return null; + } + + @Override + public List queryDeptUsersByUserId(String userId) { + return null; + } + + @Override + public Set queryUserRoles(String username) { + return null; + } + + @Override + public Set queryUserAuths(String username) { + return null; + } + + @Override + public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) { + return null; + } + + @Override + public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) { + return null; + } + + @Override + public LoginUser getUserByName(String username) { + log.error("jeecg-system服务节点不通,导致获取登录用户信息失败: " + cause.getMessage(), cause); + return null; + } + + @Override + public String translateDictFromTable(String table, String text, String code, String key) { + return null; + } + + @Override + public String translateDict(String code, String key) { + return null; + } + + @Override + public List queryPermissionDataRule(String component, String requestPath, String username) { + return null; + } + + @Override + public SysUserCacheInfo getCacheUser(String username) { + log.error("获取用户信息失败 {}", cause); + return null; + } + + @Override + public List queryUsersByUsernames(String usernames) { + return null; + } + + @Override + public List queryUsersByIds(String ids) { + return null; + } + + @Override + public List queryDepartsByOrgcodes(String orgCodes) { + return null; + } + + @Override + public List queryDepartsByIds(String ids) { + return null; + } + + @Override + public Map> translateManyDict(String dictCodes, String keys) { + return null; + } + + @Override + public List translateDictFromTableByKeys(String table, String text, String code, String keys) { + return null; + } + + @Override + public void sendEmailMsg(String email, String title, String content) { + + } + + @Override + public List getDeptUserByOrgCode(String orgCode) { + return null; + } + + @Override + public List queryDepartsByOrgIds(String ids) { + return null; + } + + @Override + public List loadCategoryDictItem(String ids) { + return null; + } + + @Override + public List loadDictItem(String dictCode, String keys) { + return null; + } + + @Override + public List getDictItems(String dictCode) { + return null; + } + + @Override + public Map> getManyDictItems(List dictCodeList) { + return null; + } + + @Override + public List loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) { + return null; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/ISysBaseAPI.java b/digital-system/src/main/java/digital/system/jeecg/group/base/ISysBaseAPI.java new file mode 100644 index 0000000..765761a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/ISysBaseAPI.java @@ -0,0 +1,387 @@ +package digital.system.jeecg.group.base; + +import com.alibaba.fastjson.JSONObject; +import digital.system.jeecg.group.CommonAPI; +import digital.base.vo.LoginUser; +import digital.bean.jeecg.dto.OnlineAuthDTO; +import digital.bean.jeecg.dto.message.*; +import digital.bean.jeecg.vo.ComboModel; +import digital.bean.jeecg.vo.DictModel; +import digital.bean.jeecg.vo.SysCategoryModel; +import digital.bean.jeecg.vo.SysDepartModel; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @Description 底层共通业务API,提供其他独立模块调用 + * @Author scott + * @Date 2019-4-20 + * @Version V1.0 + */ +public interface ISysBaseAPI extends CommonAPI { + + + /** + * 1发送系统消息 + * + * @param message 使用构造器赋值参数 如果不设置category(消息类型)则默认为2 发送系统消息 + */ + void sendSysAnnouncement(MessageDTO message); + + /** + * 2发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + void sendBusAnnouncement(BusMessageDTO message); + + /** + * 3通过模板发送消息 + * + * @param message 使用构造器赋值参数 + */ + void sendTemplateAnnouncement(TemplateMessageDTO message); + + /** + * 4通过模板发送消息 附带业务参数 + * + * @param message 使用构造器赋值参数 + */ + void sendBusTemplateAnnouncement(BusTemplateMessageDTO message); + + /** + * 5通过消息中心模板,生成推送内容 + * + * @param templateDTO 使用构造器赋值参数 + * @return + */ + String parseTemplateByCode(TemplateDTO templateDTO); + + /** + * 6根据用户id查询用户信息 + * + * @param id + * @return + */ + LoginUser getUserById(String id); + + /** + * 7通过用户账号查询角色集合 + * + * @param username + * @return + */ + List getRolesByUsername(String username); + + /** + * 8通过用户账号查询部门集合 + * + * @param username + * @return 部门 id + */ + List getDepartIdsByUsername(String username); + + /** + * 9通过用户账号查询部门 name + * + * @param username + * @return 部门 name + */ + List getDepartNamesByUsername(String username); + + + /** + * 11查询所有的父级字典,按照create_time排序 + * + * @return List 字典集合 + */ + public List queryAllDict(); + + /** + * 12查询所有分类字典 + * + * @return + */ + public List queryAllSysCategory(); + + + /** + * 14查询所有部门 作为字典信息 id -->value,departName -->text + * + * @return + */ + public List queryAllDepartBackDictModel(); + + /** + * 15根据业务类型及业务id修改消息已读 + * + * @param busType + * @param busId + */ + public void updateSysAnnounReadFlag(String busType, String busId); + + /** + * 16查询表字典 支持过滤数据 + * + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + public List queryFilterTableDictInfo(String table, String text, String code, String filterSql); + + /** + * 17查询指定table的 text code 获取字典,包含text和value + * + * @param table + * @param text + * @param code + * @param keyArray + * @return + */ + @Deprecated + public List queryTableDictByKeys(String table, String text, String code, String[] keyArray); + + /** + * 18查询所有用户 返回ComboModel + * + * @return + */ + public List queryAllUserBackCombo(); + + /** + * 19分页查询用户 返回JSONObject + * + * @param userIds 多个用户id + * @param pageNo 当前页数 + * @param pageSize 每页显示条数 + * @return + */ + public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize); + + /** + * 20获取所有角色 + * + * @return + */ + public List queryAllRole(); + + /** + * 21获取所有角色 带参 + * + * @param roleIds 默认选中角色 + * @return + */ + public List queryAllRole(String[] roleIds); + + /** + * 22通过用户账号查询角色Id集合 + * + * @param username + * @return + */ + public List getRoleIdsByUsername(String username); + + /** + * 23通过部门编号查询部门id + * + * @param orgCode + * @return + */ + public String getDepartIdsByOrgCode(String orgCode); + + /** + * 24查询所有部门 + * + * @return + */ + public List getAllSysDepart(); + + /** + * 25查找父级部门 + * + * @param departId + * @return + */ + DictModel getParentDepartId(String departId); + + /** + * 26根据部门Id获取部门负责人 + * + * @param deptId + * @return + */ + public List getDeptHeadByDepId(String deptId); + + /** + * 27给指定用户发消息 + * + * @param userIds + * @param cmd + */ + public void sendWebSocketMsg(String[] userIds, String cmd); + + /** + * 28根据id获取所有参与用户 + * + * @param userIds 多个用户id + * @return + */ + public List queryAllUserByIds(String[] userIds); + + /** + * 29将会议签到信息推动到预览 + * userIds + * + * @param userId + * @return + */ + void meetingSignWebsocket(String userId); + + /** + * 30根据name获取所有参与用户 + * + * @param userNames 多个用户账户 + * @return + */ + List queryUserByNames(String[] userNames); + + + /** + * 31获取用户的角色集合 + * + * @param username + * @return + */ + Set getUserRoleSet(String username); + + /** + * 32获取用户的权限集合 + * + * @param username + * @return + */ + Set getUserPermissionSet(String username); + + /** + * 33判断是否有online访问的权限 + * + * @param onlineAuthDTO + * @return + */ + boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO); + + /** + * 34通过部门id获取部门全部信息 + * + * @param id 部门id + * @return SysDepartModel对象 + */ + SysDepartModel selectAllById(String id); + + /** + * 35根据用户id查询用户所属公司下所有用户ids + * + * @param userId + * @return + */ + List queryDeptUsersByUserId(String userId); + + /** + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息 + * + * @param usernames + * @return + */ + List queryUsersByUsernames(String usernames); + + /** + * 37根据多个用户ID(逗号分隔),查询返回多个用户信息 + * + * @param ids + * @return + */ + List queryUsersByIds(String ids); + + /** + * 38根据多个部门编码(逗号分隔),查询返回多个部门信息 + * + * @param orgCodes + * @return + */ + List queryDepartsByOrgcodes(String orgCodes); + + /** + * 39根据多个部门id(逗号分隔),查询返回多个部门信息 + * + * @param ids + * @return + */ + List queryDepartsByIds(String ids); + + /** + * 40发送邮件消息 + * + * @param email + * @param title + * @param content + */ +// void sendEmailMsg(String email, String title, String content); + + /** + * 41 获取公司下级部门和公司下所有用户信息 + * + * @param orgCode + * @return List + */ + List getDeptUserByOrgCode(String orgCode); + + /** + * 查询分类字典翻译 + * + * @param ids 多个分类字典id + * @return List + */ + List loadCategoryDictItem(String ids); + + /** + * 根据字典code加载字典text + * + * @param dictCode 顺序:tableName,text,code + * @param keys 要查询的key + * @return + */ + List loadDictItem(String dictCode, String keys); + + /** + * 根据字典code查询字典项 + * + * @param dictCode 顺序:tableName,text,code + * @param dictCode 要查询的key + * @return + */ + List getDictItems(String dictCode); + + /** + * 根据多个字典code查询多个字典项 + * + * @param dictCodeList + * @return key = dictCode ; value=对应的字典项 + */ + Map> getManyDictItems(List dictCodeList); + + /** + * 【JSearchSelectTag下拉搜索组件专用接口】 + * 大数据量的字典表 走异步加载 即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword 过滤关键字 + * @param pageSize 分页条数 + * @return + */ + List loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/controller/JeecgController.java b/digital-system/src/main/java/digital/system/jeecg/group/base/controller/JeecgController.java new file mode 100644 index 0000000..bd0e664 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/controller/JeecgController.java @@ -0,0 +1,208 @@ +package digital.system.jeecg.group.base.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.group.query.QueryGenerator; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.shiro.SecurityUtils; +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.entity.enmus.ExcelType; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description: Controller基类 + * @Author: dangzhenghui@163.com + * @Date: 2019-4-21 8:13 + * @Version: 1.0 + */ +@Slf4j +public class JeecgController> { + /**issues/2933 JeecgController注入service时改用protected修饰,能避免重复引用service*/ + @Autowired + protected S service; + + @Value("${jeecg.path.upload}") + private String upLoadPath; + /** + * 导出excel + * + * @param request + */ + protected ModelAndView exportXls(HttpServletRequest request, T object, Class clazz, String title) { + // Step.1 组装查询条件 + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + // Step.2 获取导出数据 + List pageList = service.list(queryWrapper); + List exportList = null; + + // 过滤选中数据 + String selections = request.getParameter("selections"); + if (oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + exportList = pageList.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList()); + } else { + exportList = pageList; + } + + // Step.3 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + //此处设置的filename无效 ,前端会重更新设置一下 + mv.addObject(NormalExcelConstants.FILE_NAME, title); + mv.addObject(NormalExcelConstants.CLASS, clazz); + //update-begin--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置-------------------- + ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title); + exportParams.setImageBasePath(upLoadPath); + //update-end--Author:liusq Date:20210126 for:图片导出报错,ImageBasePath未设置---------------------- + mv.addObject(NormalExcelConstants.PARAMS,exportParams); + mv.addObject(NormalExcelConstants.DATA_LIST, exportList); + return mv; + } + /** + * 根据每页sheet数量导出多sheet + * + * @param request + * @param object 实体类 + * @param clazz 实体类class + * @param title 标题 + * @param exportFields 导出字段自定义 + * @param pageNum 每个sheet的数据条数 + * @param request + */ + protected ModelAndView exportXlsSheet(HttpServletRequest request, T object, Class clazz, String title,String exportFields,Integer pageNum) { + // Step.1 组装查询条件 + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(object, request.getParameterMap()); + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + // Step.2 计算分页sheet数据 + double total = service.count(); + int count = (int)Math.ceil(total/pageNum); + // Step.3 多sheet处理 + List> listMap = new ArrayList>(); + for (int i = 1; i <=count ; i++) { + Page page = new Page(i, pageNum); + IPage pageList = service.page(page, queryWrapper); + List records = pageList.getRecords(); + List exportList = null; + // 过滤选中数据 + String selections = request.getParameter("selections"); + if (oConvertUtils.isNotEmpty(selections)) { + List selectionList = Arrays.asList(selections.split(",")); + exportList = records.stream().filter(item -> selectionList.contains(getId(item))).collect(Collectors.toList()); + } else { + exportList = records; + } + Map map = new HashMap<>(5); + ExportParams exportParams=new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title+i,upLoadPath); + exportParams.setType(ExcelType.XSSF); + //map.put("title",exportParams); + //表格Title + map.put(NormalExcelConstants.PARAMS,exportParams); + //表格对应实体 + map.put(NormalExcelConstants.CLASS,clazz); + //数据集合 + map.put(NormalExcelConstants.DATA_LIST, exportList); + listMap.add(map); + } + // Step.4 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + //此处设置的filename无效 ,前端会重更新设置一下 + mv.addObject(NormalExcelConstants.FILE_NAME, title); + mv.addObject(NormalExcelConstants.MAP_LIST, listMap); + return mv; + } + + + /** + * 根据权限导出excel,传入导出字段参数 + * + * @param request + */ + protected ModelAndView exportXls(HttpServletRequest request, T object, Class clazz, String title,String exportFields) { + ModelAndView mv = this.exportXls(request,object,clazz,title); + mv.addObject(NormalExcelConstants.EXPORT_FIELDS,exportFields); + return mv; + } + + /** + * 获取对象ID + * + * @return + */ + private String getId(T item) { + try { + return PropertyUtils.getProperty(item, "id").toString(); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + protected Result importExcel(HttpServletRequest request, HttpServletResponse response, Class clazz) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params); + //update-begin-author:taoyan date:20190528 for:批量插入数据 + long start = System.currentTimeMillis(); + service.saveBatch(list); + //400条 saveBatch消耗时间1592毫秒 循环插入消耗时间1947毫秒 + //1200条 saveBatch消耗时间3687毫秒 循环插入消耗时间5212毫秒 + log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒"); + //update-end-author:taoyan date:20190528 for:批量插入数据 + return Result.ok("文件导入成功!数据行数:" + list.size()); + } catch (Exception e) { + //update-begin-author:taoyan date:20211124 for: 导入数据重复增加提示 + String msg = e.getMessage(); + log.error(msg, e); + if(msg!=null && msg.indexOf("Duplicate entry")>=0){ + return Result.error("文件导入失败:有重复数据!"); + }else{ + return Result.error("文件导入失败:" + e.getMessage()); + } + //update-end-author:taoyan date:20211124 for: 导入数据重复增加提示 + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return Result.error("文件导入失败!"); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/BaseCommonMapper.java b/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/BaseCommonMapper.java new file mode 100644 index 0000000..de3d1bb --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/BaseCommonMapper.java @@ -0,0 +1,22 @@ +package digital.system.jeecg.group.base.mapper; + +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; +import org.apache.ibatis.annotations.Param; +import digital.bean.jeecg.dto.LogDTO; + + +/** + * @Description: BaseCommonMapper + * @author: smcp + */ +public interface BaseCommonMapper { + + /** + * 保存日志 + * + * @param dto + */ + @InterceptorIgnore(illegalSql = "true", tenantLine = "true") + void saveLog(@Param("dto") LogDTO dto); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/xml/BaseCommonMapper.xml b/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/xml/BaseCommonMapper.xml new file mode 100644 index 0000000..c687bd0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/mapper/xml/BaseCommonMapper.xml @@ -0,0 +1,26 @@ + + + + + + + insert into sys_log (id, log_type, app_key, log_content, result, method, operate_type, request_param, ip, + user_id, + username, + cost_time, create_time) + values (#{dto.id,jdbcType=VARCHAR}, + #{dto.logType,jdbcType=INTEGER}, + #{dto.appKey,jdbcType=VARCHAR}, + #{dto.logContent,jdbcType=VARCHAR}, + #{dto.result,jdbcType=VARCHAR}, + #{dto.method,jdbcType=VARCHAR}, + #{dto.operateType,jdbcType=INTEGER}, + #{dto.requestParam,jdbcType=VARCHAR}, + #{dto.ip,jdbcType=VARCHAR}, + #{dto.userId,jdbcType=VARCHAR}, + #{dto.username,jdbcType=VARCHAR}, + #{dto.costTime,jdbcType=BIGINT}, + #{dto.createTime,jdbcType=TIMESTAMP}) + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/service/BaseCommonService.java b/digital-system/src/main/java/digital/system/jeecg/group/base/service/BaseCommonService.java new file mode 100644 index 0000000..d756b9a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/service/BaseCommonService.java @@ -0,0 +1,38 @@ +package digital.system.jeecg.group.base.service; + + +import digital.base.vo.LoginUser; +import digital.bean.jeecg.dto.LogDTO; + + +/** + * common接口 + * + * @author: smcp + */ +public interface BaseCommonService { + + /** + * 保存日志 + * @param logDTO + */ + void addLog(LogDTO logDTO); + + /** + * 保存日志 + * @param logContent + * @param logType + * @param operateType + * @param user + */ + void addLog(String logContent, Integer logType, Integer operateType, LoginUser user); + + /** + * 保存日志 + * @param logContent + * @param logType + * @param operateType + */ + void addLog(String logContent, Integer logType, Integer operateType); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/service/JeecgService.java b/digital-system/src/main/java/digital/system/jeecg/group/base/service/JeecgService.java new file mode 100644 index 0000000..ab0e04c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/service/JeecgService.java @@ -0,0 +1,12 @@ +package digital.system.jeecg.group.base.service; + +import com.baomidou.mybatisplus.extension.service.IService; + +/** + * @Description: Service基类 + * @Author: dangzhenghui@163.com + * @Date: 2019-4-21 8:13 + * @Version: 1.0 + */ +public interface JeecgService extends IService { +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/BaseCommonServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/BaseCommonServiceImpl.java new file mode 100644 index 0000000..3372b6b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/BaseCommonServiceImpl.java @@ -0,0 +1,89 @@ +package digital.system.jeecg.group.base.service.impl; + +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import digital.base.vo.LoginUser; +import digital.bean.jeecg.dto.LogDTO; +import digital.system.jeecg.group.base.mapper.BaseCommonMapper; +import digital.system.jeecg.group.base.service.BaseCommonService; +import digital.util.util.IpUtils; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.Date; + +/** + * @Description: common实现类 + * @author: smcp + */ +@Service +@Slf4j +public class BaseCommonServiceImpl implements BaseCommonService { + + @Autowired + private BaseCommonMapper baseCommonMapper; + + @Override + public void addLog(LogDTO logDTO) { + if(oConvertUtils.isEmpty(logDTO.getId())){ + logDTO.setId(String.valueOf(IdWorker.getId())); + } + //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238 + try { + baseCommonMapper.saveLog(logDTO); + } catch (Exception e) { + log.warn(" LogContent length : "+logDTO.getLogContent().length()); + log.warn(e.getMessage()); + } + } + + @Override + public void addLog(String logContent, Integer logType, Integer operatetype, LoginUser user) { + LogDTO sysLog = new LogDTO(); + sysLog.setId(String.valueOf(IdWorker.getId())); + //注解上的描述,操作日志内容 + sysLog.setLogContent(logContent); + sysLog.setLogType(logType); + sysLog.setOperateType(operatetype); + try { + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //设置IP地址 + sysLog.setIp(IpUtils.getIpAddr(request)); + } catch (Exception e) { + sysLog.setIp("127.0.0.1"); + } + //获取登录用户信息 + if(user==null){ + try { + user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + } catch (Exception e) { + //e.printStackTrace(); + } + } + if(user!=null){ + sysLog.setUserId(user.getUsername()); + sysLog.setUsername(user.getRealname()); + } + sysLog.setCreateTime(new Date()); + //保存日志(异常捕获处理,防止数据太大存储失败,导致业务失败)JT-238 + try { + baseCommonMapper.saveLog(sysLog); + } catch (Exception e) { + log.warn(" LogContent length : "+sysLog.getLogContent().length()); + log.warn(e.getMessage()); + } + } + + @Override + public void addLog(String logContent, Integer logType, Integer operateType) { + addLog(logContent, logType, operateType, null); + } + + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/JeecgServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/JeecgServiceImpl.java new file mode 100644 index 0000000..61aa644 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/base/service/impl/JeecgServiceImpl.java @@ -0,0 +1,18 @@ +package digital.system.jeecg.group.base.service.impl; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import digital.bean.jeecg.entity.JeecgEntity; +import digital.system.jeecg.group.base.service.JeecgService; + +/** + * @Description: ServiceImpl基类 + * @Author: dangzhenghui@163.com + * @Date: 2019-4-21 8:13 + * @Version: 1.0 + */ +@Slf4j +public class JeecgServiceImpl, T extends JeecgEntity> extends ServiceImpl implements JeecgService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/config/AutoPoiDictConfig.java b/digital-system/src/main/java/digital/system/jeecg/group/config/AutoPoiDictConfig.java new file mode 100644 index 0000000..6874c93 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/config/AutoPoiDictConfig.java @@ -0,0 +1,77 @@ +package digital.system.jeecg.group.config; + +import digital.system.jeecg.group.CommonAPI; +import lombok.extern.slf4j.Slf4j; +import org.jeecgframework.dict.service.AutoPoiDictServiceI; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Service; +import digital.bean.jeecg.vo.DictModel; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.ArrayList; +import java.util.List; + +/** + * 描述:AutoPoi Excel注解支持字典参数设置 + * 举例: @Excel(name = "性别", width = 15, dicCode = "sex") + * 1、导出的时候会根据字典配置,把值1,2翻译成:男、女; + * 2、导入的时候,会把男、女翻译成1,2存进数据库; + * + * @Author:scott + * @since:2019-04-09 + * @Version:1.0 + */ +@Slf4j +@Service +public class AutoPoiDictConfig implements AutoPoiDictServiceI { + final static String EXCEL_SPLIT_TAG = "_"; + final static String TEMP_EXCEL_SPLIT_TAG = "---"; + + @Lazy + @Resource + private CommonAPI commonApi; + + /** + * 通过字典查询easypoi,所需字典文本 + * + * @Author:scott + * @since:2019-04-09 + * @return + */ + @Override + public String[] queryDict(String dicTable, String dicCode, String dicText) { + List dictReplaces = new ArrayList(); + List dictList = null; + // step.1 如果没有字典表则使用系统字典表 + if (oConvertUtils.isEmpty(dicTable)) { + dictList = commonApi.queryDictItemsByCode(dicCode); + } else { + try { + dicText = oConvertUtils.getString(dicText, dicCode); + dictList = commonApi.queryTableDictItemsByCode(dicTable, dicText, dicCode); + } catch (Exception e) { + log.error(e.getMessage(),e); + } + } + + + for (DictModel t : dictList) { + if(t!=null){ + //update-begin---author:scott Date:20211220 for:[issues/I4MBB3]@Excel dicText字段的值有下划线时,导入功能不能正确解析--- + if(t.getValue().contains(EXCEL_SPLIT_TAG)){ + String val = t.getValue().replace(EXCEL_SPLIT_TAG,TEMP_EXCEL_SPLIT_TAG); + dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + val); + }else{ + dictReplaces.add(t.getText() + EXCEL_SPLIT_TAG + t.getValue()); + } + //update-end---author:20211220 Date:20211220 for:[issues/I4MBB3]@Excel dicText字段的值有下划线时,导入功能不能正确解析--- + } + } + if (dictReplaces != null && dictReplaces.size() != 0) { + log.info("---AutoPoi--Get_DB_Dict------"+ dictReplaces.toString()); + return dictReplaces.toArray(new String[dictReplaces.size()]); + } + return null; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/config/RedisConfig.java b/digital-system/src/main/java/digital/system/jeecg/group/config/RedisConfig.java new file mode 100644 index 0000000..908c9b8 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/config/RedisConfig.java @@ -0,0 +1,140 @@ +package digital.system.jeecg.group.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import digital.base.constant.CacheConstant; +import digital.system.jeecg.group.redis.receiver.RedisReceiver; +import digital.system.jeecg.group.redis.writer.JeecgRedisCacheWriter; +import lombok.extern.slf4j.Slf4j; +import org.jeecg.common.constant.GlobalConstants; +import org.springframework.cache.CacheManager; +import org.springframework.cache.annotation.CachingConfigurerSupport; +import org.springframework.cache.annotation.EnableCaching; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.cache.RedisCacheConfiguration; +import org.springframework.data.redis.cache.RedisCacheManager; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.listener.ChannelTopic; +import org.springframework.data.redis.listener.RedisMessageListenerContainer; +import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; +import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; +import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.StringRedisSerializer; + +import javax.annotation.Resource; +import java.time.Duration; + +import static java.util.Collections.singletonMap; + +/** + * 开启缓存支持 + * @author zyf + * @Return: + */ +@Slf4j +@EnableCaching +@Configuration +public class RedisConfig extends CachingConfigurerSupport { + + @Resource + private LettuceConnectionFactory lettuceConnectionFactory; + + /** + * RedisTemplate配置 + * @param lettuceConnectionFactory + * @return + */ + @Bean + public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { + log.info(" --- redis config init --- "); + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = jacksonSerializer(); + RedisTemplate redisTemplate = new RedisTemplate(); + redisTemplate.setConnectionFactory(lettuceConnectionFactory); + RedisSerializer stringSerializer = new StringRedisSerializer(); + + // key序列化 + redisTemplate.setKeySerializer(stringSerializer); + // value序列化 + redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); + // Hash key序列化 + redisTemplate.setHashKeySerializer(stringSerializer); + // Hash value序列化 + redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); + redisTemplate.afterPropertiesSet(); + return redisTemplate; + } + + /** + * 缓存配置管理器 + * + * @param factory + * @return + */ + @Bean + public CacheManager cacheManager(LettuceConnectionFactory factory) { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = jacksonSerializer(); + // 配置序列化(解决乱码的问题),并且配置缓存默认有效期 6小时 + RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(6)); + RedisCacheConfiguration redisCacheConfiguration = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)); + //.disableCachingNullValues(); + + // 以锁写入的方式创建RedisCacheWriter对象 + //update-begin-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符* + RedisCacheWriter writer = new JeecgRedisCacheWriter(factory, Duration.ofMillis(50L)); + //RedisCacheWriter.lockingRedisCacheWriter(factory); + // 创建默认缓存配置对象 + /* 默认配置,设置缓存有效期 1小时*/ + //RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(1)); + // 自定义配置test:demo 的超时时间为 5分钟 + RedisCacheManager cacheManager = RedisCacheManager.builder(writer).cacheDefaults(redisCacheConfiguration) + .withInitialCacheConfigurations(singletonMap(CacheConstant.SYS_DICT_TABLE_CACHE, + RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)).disableCachingNullValues() + .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer)))) + .withInitialCacheConfigurations(singletonMap(CacheConstant.TEST_DEMO_CACHE, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)).disableCachingNullValues())) + .withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_RANKING, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues())) + .withInitialCacheConfigurations(singletonMap(CacheConstant.PLUGIN_MALL_PAGE_LIST, RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofHours(24)).disableCachingNullValues())) + .transactionAware().build(); + //update-end-author:taoyan date:20210316 for:注解CacheEvict根据key删除redis支持通配符* + return cacheManager; + } + + /** + * redis 监听配置 + * + * @param redisConnectionFactory redis 配置 + * @return + */ + @Bean + public RedisMessageListenerContainer redisContainer(RedisConnectionFactory redisConnectionFactory, RedisReceiver redisReceiver, MessageListenerAdapter commonListenerAdapter) { + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(redisConnectionFactory); + container.addMessageListener(commonListenerAdapter, new ChannelTopic(GlobalConstants.REDIS_TOPIC_NAME)); + return container; + } + + + @Bean + MessageListenerAdapter commonListenerAdapter(RedisReceiver redisReceiver) { + MessageListenerAdapter messageListenerAdapter = new MessageListenerAdapter(redisReceiver, "onMessage"); + messageListenerAdapter.setSerializer(jacksonSerializer()); + return messageListenerAdapter; + } + + private Jackson2JsonRedisSerializer jacksonSerializer() { + Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); + objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); + jackson2JsonRedisSerializer.setObjectMapper(objectMapper); + return jackson2JsonRedisSerializer; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/config/ShiroConfig.java b/digital-system/src/main/java/digital/system/jeecg/group/config/ShiroConfig.java new file mode 100644 index 0000000..6d590ee --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/config/ShiroConfig.java @@ -0,0 +1,303 @@ +package digital.system.jeecg.group.config; + + +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.mgt.DefaultSessionStorageEvaluator; +import org.apache.shiro.mgt.DefaultSubjectDAO; +import org.apache.shiro.mgt.SecurityManager; +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.DefaultWebSecurityManager; +//import org.crazycake.shiro.IRedisManager; +//import org.crazycake.shiro.RedisCacheManager; +//import org.crazycake.shiro.RedisClusterManager; +//import org.crazycake.shiro.RedisManager; +import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; +import org.springframework.core.env.Environment; +//import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; +//import redis.clients.jedis.HostAndPort; +//import redis.clients.jedis.JedisCluster; +import digital.base.constant.CommonConstant; +import digital.config.JeecgBaseConfig; +import digital.config.shiro.filters.CustomShiroFilterFactoryBean; +import digital.config.shiro.filters.JwtFilter; +import digital.util.util.oConvertUtils; + +import javax.servlet.Filter; +import java.util.*; +/** + * @author: Scott + * @date: 2018/2/7 + * @description: shiro 配置类 + */ + +@Slf4j +@Configuration +public class ShiroConfig { + +// @Resource +// LettuceConnectionFactory lettuceConnectionFactory; + @Autowired + JeecgBaseConfig jeecgBaseConfig; + @Autowired + private Environment env; + + @Bean + public static LifecycleBeanPostProcessor lifecycleBeanPostProcessor() { + return new LifecycleBeanPostProcessor(); + } + + /** + * Filter Chain定义说明 + *

+ * 1、一个URL可以配置多个Filter,使用逗号分隔 + * 2、当设置多个过滤器时,全部验证通过,才视为通过 + * 3、部分过滤器可指定参数,如perms,roles + */ + @Bean("shiroFilterFactoryBean") + public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { + CustomShiroFilterFactoryBean shiroFilterFactoryBean = new CustomShiroFilterFactoryBean(); + shiroFilterFactoryBean.setSecurityManager(securityManager); + // 拦截器 + Map filterChainDefinitionMap = new LinkedHashMap(); + String shiroExcludeUrls = jeecgBaseConfig.getShiro().getExcludeUrls(); + if (oConvertUtils.isNotEmpty(shiroExcludeUrls)) { + String[] permissionUrl = shiroExcludeUrls.split(","); + for (String url : permissionUrl) { + filterChainDefinitionMap.put(url, "anon"); + } + } + // 配置不会被拦截的链接 顺序判断 +// filterChainDefinitionMap.put("/**/**", "anon"); //发验证码 + filterChainDefinitionMap.put("/api/cloth/submitContactInfo", "anon"); //提交公司信息 + filterChainDefinitionMap.put("/api/digital/sms", "anon"); //发验证码 + filterChainDefinitionMap.put("/api/digital/phoneLogin", "anon"); //登录 + filterChainDefinitionMap.put("/api/cloth/sms", "anon"); //发验证码 + filterChainDefinitionMap.put("/api/cloth/phoneLogin", "anon"); //登录 + filterChainDefinitionMap.put("/api/cloth/callBack", "anon"); //回调 +// filterChainDefinitionMap.put("/api/v1/clientSystem/queryByLanguageType/**", "anon"); //隐私协议 + filterChainDefinitionMap.put("/success.html", "anon"); //去掉token验证 + filterChainDefinitionMap.put("/sys/loginWithDiscord", "anon"); //c登录 + + //天津第三方接口 + filterChainDefinitionMap.put("/api/v1/getHairData", "anon"); //查询可以调用的发型数据 + filterChainDefinitionMap.put("/api/v1/swapHair", "anon"); //换发型 + filterChainDefinitionMap.put("/api/v1/getSwapHairHistoryByTaskId", "anon"); + filterChainDefinitionMap.put("/api/v1/getSwapHairHistory", "anon"); //查看换发结果数据 + + // 第二家公司第三方接口 + filterChainDefinitionMap.put("/api/v1/querySwapHairHistory", "anon"); //查看所有历史换发型结果 + filterChainDefinitionMap.put("/api/v1/queryHairData", "anon"); //查询可以调用的发型数据 + filterChainDefinitionMap.put("/api/v1/getTargetTryOnHistory", "anon"); //查看历史数据 + filterChainDefinitionMap.put("/api/v1/swapHairAsync", "anon"); //换发型 + + filterChainDefinitionMap.put("/zitaTask/savePictureTaskInfo", "anon"); //task 场景1:保存生成图片和模型结果 + filterChainDefinitionMap.put("/zitaTask/addPictureTaskInfo", "anon"); //task 场景1:生成图片和模型结果 + + filterChainDefinitionMap.put("/zitaTask/addVideoTaskInfo", "anon"); //task 场景2:生成视频任务 + filterChainDefinitionMap.put("/zitaTask/saveVideoTaskInfo", "anon"); //task 场景2:保存生成图片和模型结果 + filterChainDefinitionMap.put("/zitaTask/queryModelId", "anon"); //任务管理-根据 taskId 查 modelId + + filterChainDefinitionMap.put("/zitaPayment/webhook", "anon"); // 回调 + + filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除 + filterChainDefinitionMap.put("/api/v1/clientLogin/randomImage/**", "anon"); //登录验证码接口排除 + filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除 + filterChainDefinitionMap.put("/sys/login", "anon"); //登录接口排除 + filterChainDefinitionMap.put("/api/v1/clientLogin/login", "anon"); //登录接口排除 + filterChainDefinitionMap.put("/sys/mLogin", "anon"); //登录接口排除 + filterChainDefinitionMap.put("/sys/logout", "anon"); //登出接口排除 + filterChainDefinitionMap.put("/sys/thirdLogin/**", "anon"); //第三方登录 + filterChainDefinitionMap.put("/sys/getEncryptedString", "anon"); //获取加密串 + filterChainDefinitionMap.put("/sys/sms", "anon");//短信验证码 + filterChainDefinitionMap.put("/sys/phoneLogin", "anon");//手机登录 + filterChainDefinitionMap.put("/sys/user/checkOnlyUser", "anon");//校验用户是否存在 + filterChainDefinitionMap.put("/sys/user/register", "anon");//用户注册 + filterChainDefinitionMap.put("/sys/user/passwordChange", "anon");//用户更改密码 + filterChainDefinitionMap.put("/auth/2step-code", "anon");//登录验证码 + filterChainDefinitionMap.put("/sys/common/static/**", "anon");//图片预览 &下载文件不限制token + filterChainDefinitionMap.put("/sys/common/pdf/**", "anon");//pdf预览 + filterChainDefinitionMap.put("/generic/**", "anon");//pdf预览需要文件 + + filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码 + filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码 + filterChainDefinitionMap.put("/sys/checkAuth", "anon"); //授权接口排除 + + + filterChainDefinitionMap.put("/", "anon"); + filterChainDefinitionMap.put("/doc.html", "anon"); + filterChainDefinitionMap.put("/**/*.js", "anon"); + filterChainDefinitionMap.put("/**/*.css", "anon"); + filterChainDefinitionMap.put("/**/*.html", "anon"); + filterChainDefinitionMap.put("/**/*.svg", "anon"); + filterChainDefinitionMap.put("/**/*.pdf", "anon"); + filterChainDefinitionMap.put("/**/*.jpg", "anon"); + filterChainDefinitionMap.put("/**/*.png", "anon"); + filterChainDefinitionMap.put("/**/*.ico", "anon"); + + // update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀 + filterChainDefinitionMap.put("/**/*.ttf", "anon"); + filterChainDefinitionMap.put("/**/*.woff", "anon"); + filterChainDefinitionMap.put("/**/*.woff2", "anon"); + // update-begin--Author:sunjianlei Date:20190813 for:排除字体格式的后缀 + + filterChainDefinitionMap.put("/druid/**", "anon"); + filterChainDefinitionMap.put("/swagger-ui.html", "anon"); + filterChainDefinitionMap.put("/swagger**/**", "anon"); + filterChainDefinitionMap.put("/webjars/**", "anon"); + filterChainDefinitionMap.put("/v2/**", "anon"); + + filterChainDefinitionMap.put("/sys/annountCement/show/**", "anon"); + + //积木报表排除 + filterChainDefinitionMap.put("/jmreport/**", "anon"); + filterChainDefinitionMap.put("/**/*.js.map", "anon"); + filterChainDefinitionMap.put("/**/*.css.map", "anon"); + + //测试示例 + filterChainDefinitionMap.put("/test/bigScreen/**", "anon"); //大屏模板例子 + //filterChainDefinitionMap.put("/test/jeecgDemo/rabbitMqClientTest/**", "anon"); //MQ测试 + //filterChainDefinitionMap.put("/test/jeecgDemo/html", "anon"); //模板页面 + //filterChainDefinitionMap.put("/test/jeecgDemo/redis/**", "anon"); //redis测试 + + //websocket排除 + filterChainDefinitionMap.put("/websocket/**", "anon");//系统通知和公告 + filterChainDefinitionMap.put("/newsWebsocket/**", "anon");//CMS模块 + filterChainDefinitionMap.put("/vxeSocket/**", "anon");//JVxeTable无痕刷新示例 + + //wps + filterChainDefinitionMap.put("/v1/**", "anon"); + + //性能监控 TODO 存在安全漏洞泄露TOEKN(durid连接池也有) + filterChainDefinitionMap.put("/actuator/**", "anon"); + + //测试模块排除 + filterChainDefinitionMap.put("/test/seata/**", "anon"); + + // 添加自己的过滤器并且取名为jwt + Map filterMap = new HashMap(1); + //如果cloudServer为空 则说明是单体 需要加载跨域配置【微服务跨域切换】 + Object cloudServer = env.getProperty(CommonConstant.CLOUD_SERVER_KEY); + filterMap.put("jwt", new JwtFilter(cloudServer == null)); + shiroFilterFactoryBean.setFilters(filterMap); + // " + filterConditions); + + queryWrapper.and(andWrapper -> { + for (int i = 0; i < filterConditions.size(); i++) { + QueryCondition rule = filterConditions.get(i); + if (oConvertUtils.isNotEmpty(rule.getField()) + && oConvertUtils.isNotEmpty(rule.getRule()) + && oConvertUtils.isNotEmpty(rule.getVal())) { + + log.debug("SuperQuery ==> " + rule.toString()); + + //update-begin-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错 + Object queryValue = rule.getVal(); + if("date".equals(rule.getType())){ + queryValue = DateUtils.str2Date(rule.getVal(),DateUtils.date_sdf.get()); + }else if("datetime".equals(rule.getType())){ + queryValue = DateUtils.str2Date(rule.getVal(), DateUtils.datetimeFormat.get()); + } + // update-begin--author:sunjianlei date:20210702 for:【/issues/I3VR8E】高级查询没有类型转换,查询参数都是字符串类型 ---- + String dbType = rule.getDbType(); + if (oConvertUtils.isNotEmpty(dbType)) { + try { + String valueStr = String.valueOf(queryValue); + switch (dbType.toLowerCase().trim()) { + case "int": + queryValue = Integer.parseInt(valueStr); + break; + case "bigdecimal": + queryValue = new BigDecimal(valueStr); + break; + case "short": + queryValue = Short.parseShort(valueStr); + break; + case "long": + queryValue = Long.parseLong(valueStr); + break; + case "float": + queryValue = Float.parseFloat(valueStr); + break; + case "double": + queryValue = Double.parseDouble(valueStr); + break; + case "boolean": + queryValue = Boolean.parseBoolean(valueStr); + break; + default: + } + } catch (Exception e) { + log.error("高级查询值转换失败:", e); + } + } + // update-begin--author:sunjianlei date:20210702 for:【/issues/I3VR8E】高级查询没有类型转换,查询参数都是字符串类型 ---- + addEasyQuery(andWrapper, fieldColumnMap.get(rule.getField()), QueryRuleEnum.getByValue(rule.getRule()), queryValue); + //update-end-author:taoyan date:20201228 for: 【高级查询】 oracle 日期等于查询报错 + + // 如果拼接方式是OR,就拼接OR + if (MatchTypeEnum.OR == matchType && i < (filterConditions.size() - 1)) { + andWrapper.or(); + } + } + } + //return andWrapper; + }); + } catch (UnsupportedEncodingException e) { + log.error("--高级查询参数转码失败:" + superQueryParams, e); + } catch (Exception e) { + log.error("--高级查询拼接失败:" + e.getMessage()); + e.printStackTrace(); + } + // update-end--Author:sunjianlei Date:20200325 for:高级查询的条件要用括号括起来,防止和用户的其他条件冲突 ------- + } + //log.info(" superQuery getCustomSqlSegment: "+ queryWrapper.getCustomSqlSegment()); + } + /** + * 根据所传的值 转化成对应的比较方式 + * 支持><= like in ! + * @param value + * @return + */ + public static QueryRuleEnum convert2Rule(Object value) { + // 避免空数据 + // update-begin-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常 + if (value == null) { + return QueryRuleEnum.EQ; + } + String val = (value + "").toString().trim(); + if (val.length() == 0) { + return QueryRuleEnum.EQ; + } + // update-end-author:taoyan date:20210629 for: 查询条件输入空格导致return null后续判断导致抛出null异常 + QueryRuleEnum rule =null; + + //update-begin--Author:scott Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284------------------- + //TODO 此处规则,只适用于 le lt ge gt + // step 2 .>= =< + int length2 = 2; + int length3 = 3; + if (rule == null && val.length() >= length3) { + if(QUERY_SEPARATE_KEYWORD.equals(val.substring(length2, length3))){ + rule = QueryRuleEnum.getByValue(val.substring(0, 2)); + } + } + // step 1 .> < + if (rule == null && val.length() >= length2) { + if(QUERY_SEPARATE_KEYWORD.equals(val.substring(1, length2))){ + rule = QueryRuleEnum.getByValue(val.substring(0, 1)); + } + } + //update-end--Author:scott Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284--------------------- + + // step 3 like + //update-begin-author:taoyan for: /issues/3382 默认带*就走模糊,但是如果只有一个*,那么走等于查询 + if(rule == null && val.equals(STAR)){ + rule = QueryRuleEnum.EQ; + } + //update-end-author:taoyan for: /issues/3382 默认带*就走模糊,但是如果只有一个*,那么走等于查询 + if (rule == null && val.contains(STAR)) { + if (val.startsWith(STAR) && val.endsWith(STAR)) { + rule = QueryRuleEnum.LIKE; + } else if (val.startsWith(STAR)) { + rule = QueryRuleEnum.LEFT_LIKE; + } else if(val.endsWith(STAR)){ + rule = QueryRuleEnum.RIGHT_LIKE; + } + } + + // step 4 in + if (rule == null && val.contains(COMMA)) { + //TODO in 查询这里应该有个bug 如果一字段本身就是多选 此时用in查询 未必能查询出来 + rule = QueryRuleEnum.IN; + } + // step 5 != + if(rule == null && val.startsWith(NOT_EQUAL)){ + rule = QueryRuleEnum.NE; + } + // step 6 xx+xx+xx 这种情况适用于如果想要用逗号作精确查询 但是系统默认逗号走in 所以可以用++替换【此逻辑作废】 + if(rule == null && val.indexOf(QUERY_COMMA_ESCAPE)>0){ + rule = QueryRuleEnum.EQ_WITH_ADD; + } + + //update-begin--Author:taoyan Date:20201229 for:initQueryWrapper组装sql查询条件错误 #284--------------------- + //特殊处理:Oracle的表达式to_date('xxx','yyyy-MM-dd')含有逗号,会被识别为in查询,转为等于查询 + if(rule == QueryRuleEnum.IN && val.indexOf(YYYY_MM_DD)>=0 && val.indexOf(TO_DATE)>=0){ + rule = QueryRuleEnum.EQ; + } + //update-end--Author:taoyan Date:20201229 for:initQueryWrapper组装sql查询条件错误 #284--------------------- + + return rule != null ? rule : QueryRuleEnum.EQ; + } + + /** + * 替换掉关键字字符 + * + * @param rule + * @param value + * @return + */ + private static Object replaceValue(QueryRuleEnum rule, Object value) { + if (rule == null) { + return null; + } + if (! (value instanceof String)){ + return value; + } + String val = (value + "").toString().trim(); + //update-begin-author:taoyan date:20220302 for: 查询条件的值为等号(=)bug #3443 + if(QueryRuleEnum.EQ.getValue().equals(val)){ + return val; + } + //update-end-author:taoyan date:20220302 for: 查询条件的值为等号(=)bug #3443 + if (rule == QueryRuleEnum.LIKE) { + value = val.substring(1, val.length() - 1); + //mysql 模糊查询之特殊字符下划线 (_、\) + value = specialStrConvert(value.toString()); + } else if (rule == QueryRuleEnum.LEFT_LIKE || rule == QueryRuleEnum.NE) { + value = val.substring(1); + //mysql 模糊查询之特殊字符下划线 (_、\) + value = specialStrConvert(value.toString()); + } else if (rule == QueryRuleEnum.RIGHT_LIKE) { + value = val.substring(0, val.length() - 1); + //mysql 模糊查询之特殊字符下划线 (_、\) + value = specialStrConvert(value.toString()); + } else if (rule == QueryRuleEnum.IN) { + value = val.split(","); + } else if (rule == QueryRuleEnum.EQ_WITH_ADD) { + value = val.replaceAll("\\+\\+", COMMA); + }else { + //update-begin--Author:scott Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284------------------- + if(val.startsWith(rule.getValue())){ + //TODO 此处逻辑应该注释掉-> 如果查询内容中带有查询匹配规则符号,就会被截取的(比如:>=您好) + value = val.replaceFirst(rule.getValue(),""); + }else if(val.startsWith(rule.getCondition()+QUERY_SEPARATE_KEYWORD)){ + value = val.replaceFirst(rule.getCondition()+QUERY_SEPARATE_KEYWORD,"").trim(); + } + //update-end--Author:scott Date:20190724 for:initQueryWrapper组装sql查询条件错误 #284------------------- + } + return value; + } + + private static void addQueryByRule(QueryWrapper queryWrapper,String name,String type,String value,QueryRuleEnum rule) throws ParseException { + if(oConvertUtils.isNotEmpty(value)) { + //update-begin--Author:sunjianlei Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 ------------------- + // 针对数字类型字段,多值查询 + if(value.contains(COMMA)){ + Object[] temp = Arrays.stream(value.split(COMMA)).map(v -> { + try { + return QueryGenerator.parseByType(v, type, rule); + } catch (ParseException e) { + e.printStackTrace(); + return v; + } + }).toArray(); + addEasyQuery(queryWrapper, name, rule, temp); + return; + } + Object temp = QueryGenerator.parseByType(value, type, rule); + addEasyQuery(queryWrapper, name, rule, temp); + //update-end--Author:sunjianlei Date:20220104 for:【JTC-409】修复逗号分割情况下没有转换类型,导致类型严格的数据库查询报错 ------------------- + } + } + + /** + * 根据类型转换给定的值 + * @param value + * @param type + * @param rule + * @return + * @throws ParseException + */ + private static Object parseByType(String value, String type, QueryRuleEnum rule) throws ParseException { + Object temp; + switch (type) { + case "class java.lang.Integer": + temp = Integer.parseInt(value); + break; + case "class java.math.BigDecimal": + temp = new BigDecimal(value); + break; + case "class java.lang.Short": + temp = Short.parseShort(value); + break; + case "class java.lang.Long": + temp = Long.parseLong(value); + break; + case "class java.lang.Float": + temp = Float.parseFloat(value); + break; + case "class java.lang.Double": + temp = Double.parseDouble(value); + break; + case "class java.util.Date": + temp = getDateQueryByRule(value, rule); + break; + default: + temp = value; + break; + } + return temp; + } + + /** + * 获取日期类型的值 + * @param value + * @param rule + * @return + * @throws ParseException + */ + private static Date getDateQueryByRule(String value,QueryRuleEnum rule) throws ParseException { + Date date = null; + int length = 10; + if(value.length()==length) { + if(rule==QueryRuleEnum.GE) { + //比较大于 + date = getTime().parse(value + " 00:00:00"); + }else if(rule==QueryRuleEnum.LE) { + //比较小于 + date = getTime().parse(value + " 23:59:59"); + } + //TODO 日期类型比较特殊 可能oracle下不一定好使 + } + if(date==null) { + date = getTime().parse(value); + } + return date; + } + + /** + * 根据规则走不同的查询 + * @param queryWrapper QueryWrapper + * @param name 字段名字 + * @param rule 查询规则 + * @param value 查询条件值 + */ + public static void addEasyQuery(QueryWrapper queryWrapper, String name, QueryRuleEnum rule, Object value) { + if (value == null || rule == null || oConvertUtils.isEmpty(value)) { + return; + } + name = oConvertUtils.camelToUnderline(name); + log.info("---查询过滤器,Query规则---field:{}, rule:{}, value:{}",name,rule.getValue(),value); + switch (rule) { + case GT: + queryWrapper.gt(name, value); + break; + case GE: + queryWrapper.ge(name, value); + break; + case LT: + queryWrapper.lt(name, value); + break; + case LE: + queryWrapper.le(name, value); + break; + case EQ: + case EQ_WITH_ADD: + queryWrapper.eq(name, value); + break; + case NE: + queryWrapper.ne(name, value); + break; + case IN: + if(value instanceof String) { + queryWrapper.in(name, (Object[])value.toString().split(COMMA)); + }else if(value instanceof String[]) { + queryWrapper.in(name, (Object[]) value); + } + //update-begin-author:taoyan date:20200909 for:【bug】in 类型多值查询 不适配postgresql #1671 + else if(value.getClass().isArray()) { + queryWrapper.in(name, (Object[])value); + }else { + queryWrapper.in(name, value); + } + //update-end-author:taoyan date:20200909 for:【bug】in 类型多值查询 不适配postgresql #1671 + break; + case LIKE: + queryWrapper.like(name, value); + break; + case LEFT_LIKE: + queryWrapper.likeLeft(name, value); + break; + case RIGHT_LIKE: + queryWrapper.likeRight(name, value); + break; + default: + log.info("--查询规则未匹配到---"); + break; + } + } + /** + * + * @param name + * @return + */ + private static boolean judgedIsUselessField(String name) { + return "class".equals(name) || "ids".equals(name) + || "page".equals(name) || "rows".equals(name) + || "sort".equals(name) || "order".equals(name); + } + + + + /** + * 获取请求对应的数据权限规则 TODO 相同列权限多个 有问题 + * @return + */ + public static Map getRuleMap() { + Map ruleMap = new HashMap<>(5); + List list = JeecgDataAutorUtils.loadDataSearchConditon(); + if (list != null && list.size() > 0) { + if (list.get(0) == null) { + return ruleMap; + } + for (SysPermissionDataRuleModel rule : list) { + String column = rule.getRuleColumn(); + if (QueryRuleEnum.SQL_RULES.getValue().equals(rule.getRuleConditions())) { + column = SQL_RULES_COLUMN + rule.getId(); + } + ruleMap.put(column, rule); + } + } + return ruleMap; + } + + private static void addRuleToQueryWrapper(SysPermissionDataRuleModel dataRule, String name, Class propertyType, QueryWrapper queryWrapper) { + QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions()); + if(rule.equals(QueryRuleEnum.IN) && ! propertyType.equals(String.class)) { + String[] values = dataRule.getRuleValue().split(","); + Object[] objs = new Object[values.length]; + for (int i = 0; i < values.length; i++) { + objs[i] = NumberUtils.parseNumber(values[i], propertyType); + } + addEasyQuery(queryWrapper, name, rule, objs); + }else { + if (propertyType.equals(String.class)) { + addEasyQuery(queryWrapper, name, rule, converRuleValue(dataRule.getRuleValue())); + }else if (propertyType.equals(Date.class)) { + String dateStr =converRuleValue(dataRule.getRuleValue()); + int length = 10; + if(dateStr.length()==length){ + addEasyQuery(queryWrapper, name, rule, DateUtils.str2Date(dateStr,DateUtils.date_sdf.get())); + }else{ + addEasyQuery(queryWrapper, name, rule, DateUtils.str2Date(dateStr,DateUtils.datetimeFormat.get())); + } + }else { + addEasyQuery(queryWrapper, name, rule, NumberUtils.parseNumber(dataRule.getRuleValue(), propertyType)); + } + } + } + + public static String converRuleValue(String ruleValue) { + String value = JwtUtil.getUserSystemData(ruleValue,null); + return value!= null ? value : ruleValue; + } + + /** + * @author: scott + * @Description: 去掉值前后单引号 + * @date: 2020/3/19 21:26 + * @param ruleValue: + * @Return: java.lang.String + */ + public static String trimSingleQuote(String ruleValue) { + if (oConvertUtils.isEmpty(ruleValue)) { + return ""; + } + if (ruleValue.startsWith(QueryGenerator.SQL_SQ)) { + ruleValue = ruleValue.substring(1); + } + if (ruleValue.endsWith(QueryGenerator.SQL_SQ)) { + ruleValue = ruleValue.substring(0, ruleValue.length() - 1); + } + return ruleValue; + } + + public static String getSqlRuleValue(String sqlRule){ + try { + Set varParams = getSqlRuleParams(sqlRule); + for(String var:varParams){ + String tempValue = converRuleValue(var); + sqlRule = sqlRule.replace("#{"+var+"}",tempValue); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return sqlRule; + } + + /** + * 获取sql中的#{key} 这个key组成的set + */ + public static Set getSqlRuleParams(String sql) { + if(oConvertUtils.isEmpty(sql)){ + return null; + } + Set varParams = new HashSet(); + String regex = "\\#\\{\\w+\\}"; + + Pattern p = Pattern.compile(regex); + Matcher m = p.matcher(sql); + while(m.find()){ + String var = m.group(); + varParams.add(var.substring(var.indexOf("{")+1,var.indexOf("}"))); + } + return varParams; + } + + /** + * 获取查询条件 + * @param field + * @param alias + * @param value + * @param isString + * @return + */ + public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString) { + return getSingleQueryConditionSql(field, alias, value, isString,null); + } + + /** + * 报表获取查询条件 支持多数据源 + * @param field + * @param alias + * @param value + * @param isString + * @param dataBaseType + * @return + */ + public static String getSingleQueryConditionSql(String field,String alias,Object value,boolean isString, String dataBaseType) { + if (value == null) { + return ""; + } + field = alias+oConvertUtils.camelToUnderline(field); + QueryRuleEnum rule = QueryGenerator.convert2Rule(value); + return getSingleSqlByRule(rule, field, value, isString, dataBaseType); + } + + /** + * 获取单个查询条件的值 + * @param rule + * @param field + * @param value + * @param isString + * @param dataBaseType + * @return + */ + private static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString, String dataBaseType) { + String res = ""; + switch (rule) { + case GT: + res =field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType); + break; + case GE: + res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType); + break; + case LT: + res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType); + break; + case LE: + res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType); + break; + case EQ: + res = field+rule.getValue()+getFieldConditionValue(value, isString, dataBaseType); + break; + case EQ_WITH_ADD: + res = field+" = "+getFieldConditionValue(value, isString, dataBaseType); + break; + case NE: + res = field+" <> "+getFieldConditionValue(value, isString, dataBaseType); + break; + case IN: + res = field + " in "+getInConditionValue(value, isString); + break; + case LIKE: + res = field + " like "+getLikeConditionValue(value); + break; + case LEFT_LIKE: + res = field + " like "+getLikeConditionValue(value); + break; + case RIGHT_LIKE: + res = field + " like "+getLikeConditionValue(value); + break; + default: + res = field+" = "+getFieldConditionValue(value, isString, dataBaseType); + break; + } + return res; + } + + + /** + * 获取单个查询条件的值 + * @param rule + * @param field + * @param value + * @param isString + * @return + */ + private static String getSingleSqlByRule(QueryRuleEnum rule,String field,Object value,boolean isString) { + return getSingleSqlByRule(rule, field, value, isString, null); + } + + /** + * 获取查询条件的值 + * @param value + * @param isString + * @param dataBaseType + * @return + */ + private static String getFieldConditionValue(Object value,boolean isString, String dataBaseType) { + String str = value.toString().trim(); + if(str.startsWith(SymbolConstant.EXCLAMATORY_MARK)) { + str = str.substring(1); + }else if(str.startsWith(QueryRuleEnum.GE.getValue())) { + str = str.substring(2); + }else if(str.startsWith(QueryRuleEnum.LE.getValue())) { + str = str.substring(2); + }else if(str.startsWith(QueryRuleEnum.GT.getValue())) { + str = str.substring(1); + }else if(str.startsWith(QueryRuleEnum.LT.getValue())) { + str = str.substring(1); + }else if(str.indexOf(QUERY_COMMA_ESCAPE)>0) { + str = str.replaceAll("\\+\\+", COMMA); + } + if(dataBaseType==null){ + dataBaseType = getDbType(); + } + if(isString) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType)){ + return " N'"+str+"' "; + }else{ + return " '"+str+"' "; + } + }else { + // 如果不是字符串 有一种特殊情况 popup调用都走这个逻辑 参数传递的可能是“‘admin’”这种格式的 + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(dataBaseType) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){ + return " N"+str; + } + return value.toString(); + } + } + + private static String getInConditionValue(Object value,boolean isString) { + //update-begin-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错 + String[] temp = value.toString().split(","); + if(temp.length==0){ + return "('')"; + } + if(isString) { + List res = new ArrayList<>(); + for (String string : temp) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + res.add("N'"+string+"'"); + }else{ + res.add("'"+string+"'"); + } + } + return "("+String.join("," ,res)+")"; + }else { + return "("+value.toString()+")"; + } + //update-end-author:taoyan date:20210628 for: 查询条件如果输入,导致sql报错 + } + + private static String getLikeConditionValue(Object value) { + String str = value.toString().trim(); + if(str.startsWith(SymbolConstant.ASTERISK) && str.endsWith(SymbolConstant.ASTERISK)) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + return "N'%"+str.substring(1,str.length()-1)+"%'"; + }else{ + return "'%"+str.substring(1,str.length()-1)+"%'"; + } + }else if(str.startsWith(SymbolConstant.ASTERISK)) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + return "N'%"+str.substring(1)+"'"; + }else{ + return "'%"+str.substring(1)+"'"; + } + }else if(str.endsWith(SymbolConstant.ASTERISK)) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + return "N'"+str.substring(0,str.length()-1)+"%'"; + }else{ + return "'"+str.substring(0,str.length()-1)+"%'"; + } + }else { + if(str.indexOf(SymbolConstant.PERCENT_SIGN)>=0) { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + if(str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){ + return "N"+str; + }else{ + return "N"+"'"+str+"'"; + } + }else{ + if(str.startsWith(SymbolConstant.SINGLE_QUOTATION_MARK) && str.endsWith(SymbolConstant.SINGLE_QUOTATION_MARK)){ + return str; + }else{ + return "'"+str+"'"; + } + } + }else { + if(DataBaseConstant.DB_TYPE_SQLSERVER.equals(getDbType())){ + return "N'%"+str+"%'"; + }else{ + return "'%"+str+"%'"; + } + } + } + } + + /** + * 根据权限相关配置生成相关的SQL 语句 + * @param clazz + * @return + */ + @SuppressWarnings({ "unchecked", "rawtypes" }) + public static String installAuthJdbc(Class clazz) { + StringBuffer sb = new StringBuffer(); + //权限查询 + Map ruleMap = getRuleMap(); + PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(clazz); + String sqlAnd = " and "; + for (String c : ruleMap.keySet()) { + if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){ + sb.append(sqlAnd+getSqlRuleValue(ruleMap.get(c).getRuleValue())); + } + } + String name, column; + for (int i = 0; i < origDescriptors.length; i++) { + name = origDescriptors[i].getName(); + if (judgedIsUselessField(name)) { + continue; + } + if(ruleMap.containsKey(name)) { + column = getTableFieldName(clazz, name); + if(column==null){ + continue; + } + SysPermissionDataRuleModel dataRule = ruleMap.get(name); + QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions()); + Class propType = origDescriptors[i].getPropertyType(); + boolean isString = propType.equals(String.class); + Object value; + if(isString) { + value = converRuleValue(dataRule.getRuleValue()); + }else { + value = NumberUtils.parseNumber(dataRule.getRuleValue(),propType); + } + String filedSql = getSingleSqlByRule(rule, oConvertUtils.camelToUnderline(column), value,isString); + sb.append(sqlAnd+filedSql); + } + } + log.info("query auth sql is:"+sb.toString()); + return sb.toString(); + } + + /** + * 根据权限相关配置 组装mp需要的权限 + * @param queryWrapper + * @param clazz + * @return + */ + public static void installAuthMplus(QueryWrapper queryWrapper,Class clazz) { + //权限查询 + Map ruleMap = getRuleMap(); + PropertyDescriptor[] origDescriptors = PropertyUtils.getPropertyDescriptors(clazz); + for (String c : ruleMap.keySet()) { + if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){ + queryWrapper.and(i ->i.apply(getSqlRuleValue(ruleMap.get(c).getRuleValue()))); + } + } + String name, column; + for (int i = 0; i < origDescriptors.length; i++) { + name = origDescriptors[i].getName(); + if (judgedIsUselessField(name)) { + continue; + } + column = getTableFieldName(clazz, name); + if(column==null){ + continue; + } + if(ruleMap.containsKey(name)) { + addRuleToQueryWrapper(ruleMap.get(name), column, origDescriptors[i].getPropertyType(), queryWrapper); + } + } + } + + /** + * 转换sql中的系统变量 + * @param sql + * @return + */ + public static String convertSystemVariables(String sql){ + return getSqlRuleValue(sql); + } + + /** + * 获取所有配置的权限 返回sql字符串 不受字段限制 配置什么就拿到什么 + * @return + */ + public static String getAllConfigAuth() { + StringBuffer sb = new StringBuffer(); + //权限查询 + Map ruleMap = getRuleMap(); + String sqlAnd = " and "; + for (String c : ruleMap.keySet()) { + SysPermissionDataRuleModel dataRule = ruleMap.get(c); + String ruleValue = dataRule.getRuleValue(); + if(oConvertUtils.isEmpty(ruleValue)){ + continue; + } + if(oConvertUtils.isNotEmpty(c) && c.startsWith(SQL_RULES_COLUMN)){ + sb.append(sqlAnd+getSqlRuleValue(ruleValue)); + }else{ + boolean isString = false; + ruleValue = ruleValue.trim(); + if(ruleValue.startsWith("'") && ruleValue.endsWith("'")){ + isString = true; + ruleValue = ruleValue.substring(1,ruleValue.length()-1); + } + QueryRuleEnum rule = QueryRuleEnum.getByValue(dataRule.getRuleConditions()); + String value = converRuleValue(ruleValue); + String filedSql = getSingleSqlByRule(rule, c, value,isString); + sb.append(sqlAnd+filedSql); + } + } + log.info("query auth sql is = "+sb.toString()); + return sb.toString(); + } + + + + /** + * 获取系统数据库类型 + */ + private static String getDbType(){ + return CommonUtils.getDatabaseType(); + } + + + /** + * 获取class的 包括父类的 + * @param clazz + * @return + */ + private static List getClassFields(Class clazz) { + List list = new ArrayList(); + Field[] fields; + do{ + fields = clazz.getDeclaredFields(); + for(int i = 0;i clazz, String name) { + try { + //如果字段加注解了@TableField(exist = false),不走DB查询 + Field field = null; + try { + field = clazz.getDeclaredField(name); + } catch (NoSuchFieldException e) { + //e.printStackTrace(); + } + + //如果为空,则去父类查找字段 + if (field == null) { + List allFields = getClassFields(clazz); + List searchFields = allFields.stream().filter(a -> a.getName().equals(name)).collect(Collectors.toList()); + if(searchFields!=null && searchFields.size()>0){ + field = searchFields.get(0); + } + } + + if (field != null) { + TableField tableField = field.getAnnotation(TableField.class); + if (tableField != null){ + if(tableField.exist() == false){ + //如果设置了TableField false 这个字段不需要处理 + return null; + }else{ + String column = tableField.value(); + //如果设置了TableField value 这个字段是实体字段 + if(!"".equals(column)){ + return column; + } + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return name; + } + + /** + * mysql 模糊查询之特殊字符下划线 (_、\) + * + * @param value: + * @Return: java.lang.String + */ + private static String specialStrConvert(String value) { + if (DataBaseConstant.DB_TYPE_MYSQL.equals(getDbType()) || DataBaseConstant.DB_TYPE_MARIADB.equals(getDbType())) { + String[] specialStr = QueryGenerator.LIKE_MYSQL_SPECIAL_STRS.split(","); + for (String str : specialStr) { + if (value.indexOf(str) !=-1) { + value = value.replace(str, "\\" + str); + } + } + } + return value; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/query/QueryRuleEnum.java b/digital-system/src/main/java/digital/system/jeecg/group/query/QueryRuleEnum.java new file mode 100644 index 0000000..ac08cef --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/query/QueryRuleEnum.java @@ -0,0 +1,88 @@ +package digital.system.jeecg.group.query; + + +import digital.util.util.oConvertUtils; + +/** + * Query 规则 常量 + * + * @Author Scott + * @Date 2019年02月14日 + */ +public enum QueryRuleEnum { + + /**查询规则 大于*/ + GT(">", "gt", "大于"), + /**查询规则 大于等于*/ + GE(">=","ge","大于等于"), + /**查询规则 小于*/ + LT("<","lt","小于"), + /**查询规则 小于等于*/ + LE("<=","le","小于等于"), + /**查询规则 等于*/ + EQ("=","eq","等于"), + /**查询规则 不等于*/ + NE("!=","ne","不等于"), + /**查询规则 包含*/ + IN("IN","in","包含"), + /**查询规则 全模糊*/ + LIKE("LIKE","like","全模糊"), + /**查询规则 左模糊*/ + LEFT_LIKE("LEFT_LIKE","left_like","左模糊"), + /**查询规则 右模糊*/ + RIGHT_LIKE("RIGHT_LIKE","right_like","右模糊"), + /**查询规则 带加号等于*/ + EQ_WITH_ADD("EQWITHADD","eq_with_add","带加号等于"), + /**查询规则 多词模糊匹配*/ + LIKE_WITH_AND("LIKEWITHAND","like_with_and","多词模糊匹配————暂时未用上"), + /**查询规则 自定义SQL片段*/ + SQL_RULES("USE_SQL_RULES","ext","自定义SQL片段"); + + private String value; + + private String condition; + + private String msg; + + QueryRuleEnum(String value, String condition, String msg){ + this.value = value; + this.condition = condition; + this.msg = msg; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getMsg() { + return msg; + } + + public void setMsg(String msg) { + this.msg = msg; + } + + public String getCondition() { + return condition; + } + + public void setCondition(String condition) { + this.condition = condition; + } + + public static QueryRuleEnum getByValue(String value){ + if(oConvertUtils.isEmpty(value)) { + return null; + } + for(QueryRuleEnum val :values()){ + if (val.getValue().equals(value) || val.getCondition().equals(value)){ + return val; + } + } + return null; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/redis/client/JeecgRedisClient.java b/digital-system/src/main/java/digital/system/jeecg/group/redis/client/JeecgRedisClient.java new file mode 100644 index 0000000..7c5bb07 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/redis/client/JeecgRedisClient.java @@ -0,0 +1,35 @@ +package digital.system.jeecg.group.redis.client; + + +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; +import digital.base.constant.GlobalConstants; +import digital.bean.jeecg.BaseMap; + +import javax.annotation.Resource; + +/** +* @Description: redis客户端 +* @author: scott +* @date: 2020/01/01 16:01 +*/ +@Configuration +public class JeecgRedisClient { + + @Resource + private RedisTemplate redisTemplate; + + + /** + * 发送消息 + * + * @param handlerName + * @param params + */ + public void sendMessage(String handlerName, BaseMap params) { +// params.put(GlobalConstants.HANDLER_NAME, handlerName); +// redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params); + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/redis/listener/JeecgRedisListener.java b/digital-system/src/main/java/digital/system/jeecg/group/redis/listener/JeecgRedisListener.java new file mode 100644 index 0000000..864c2de --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/redis/listener/JeecgRedisListener.java @@ -0,0 +1,19 @@ +package digital.system.jeecg.group.redis.listener; + + +import digital.bean.jeecg.BaseMap; + +/** + * @Description: 自定义消息监听 + * @author: scott + * @date: 2020/01/01 16:02 + */ +public interface JeecgRedisListener { + /** + * 接受消息 + * + * @param message + */ + void onMessage(BaseMap message); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/redis/receiver/RedisReceiver.java b/digital-system/src/main/java/digital/system/jeecg/group/redis/receiver/RedisReceiver.java new file mode 100644 index 0000000..5e0d095 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/redis/receiver/RedisReceiver.java @@ -0,0 +1,33 @@ +package digital.system.jeecg.group.redis.receiver; + + +import cn.hutool.core.util.ObjectUtil; +import lombok.Data; +import org.springframework.stereotype.Component; +import digital.base.constant.GlobalConstants; +import digital.bean.jeecg.BaseMap; +import digital.system.jeecg.group.redis.listener.JeecgRedisListener; +import digital.util.util.SpringContextHolder; + +/** + * @author zyf + */ +@Component +@Data +public class RedisReceiver { + + + /** + * 接受消息并调用业务逻辑处理器 + * + * @param params + */ + public void onMessage(BaseMap params) { + Object handlerName = params.get(GlobalConstants.HANDLER_NAME); + JeecgRedisListener messageListener = SpringContextHolder.getHandler(handlerName.toString(), JeecgRedisListener.class); + if (ObjectUtil.isNotEmpty(messageListener)) { + messageListener.onMessage(params); + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/redis/writer/JeecgRedisCacheWriter.java b/digital-system/src/main/java/digital/system/jeecg/group/redis/writer/JeecgRedisCacheWriter.java new file mode 100644 index 0000000..3863413 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/redis/writer/JeecgRedisCacheWriter.java @@ -0,0 +1,250 @@ +package digital.system.jeecg.group.redis.writer; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.dao.PessimisticLockingFailureException; +import org.springframework.data.redis.cache.CacheStatistics; +import org.springframework.data.redis.cache.CacheStatisticsCollector; +import org.springframework.data.redis.cache.RedisCacheWriter; +import org.springframework.data.redis.connection.RedisConnection; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.connection.RedisStringCommands.SetOption; +import org.springframework.data.redis.core.types.Expiration; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; + +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Collections; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.function.Consumer; +import java.util.function.Function; + +/** + * 该类参照 DefaultRedisCacheWriter 重写了 remove 方法实现通配符*删除 + * + * @author: scott + * @date: 2020/01/01 16:18 + */ +@Slf4j +public class JeecgRedisCacheWriter implements RedisCacheWriter { + + private final RedisConnectionFactory connectionFactory; + private final Duration sleepTime; + + public JeecgRedisCacheWriter(RedisConnectionFactory connectionFactory) { + this(connectionFactory, Duration.ZERO); + } + + public JeecgRedisCacheWriter(RedisConnectionFactory connectionFactory, Duration sleepTime) { + Assert.notNull(connectionFactory, "ConnectionFactory must not be null!"); + Assert.notNull(sleepTime, "SleepTime must not be null!"); + this.connectionFactory = connectionFactory; + this.sleepTime = sleepTime; + } + + @Override + public void put(String name, byte[] key, byte[] value, @Nullable Duration ttl) { + Assert.notNull(name, "Name must not be null!"); + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(value, "Value must not be null!"); + this.execute(name, (connection) -> { + if (shouldExpireWithin(ttl)) { + connection.set(key, value, Expiration.from(ttl.toMillis(), TimeUnit.MILLISECONDS), SetOption.upsert()); + } else { + connection.set(key, value); + } + + return "OK"; + }); + } + + @Override + public byte[] get(String name, byte[] key) { + Assert.notNull(name, "Name must not be null!"); + Assert.notNull(key, "Key must not be null!"); + return (byte[])this.execute(name, (connection) -> { + return connection.get(key); + }); + } + + @Override + public byte[] putIfAbsent(String name, byte[] key, byte[] value, @Nullable Duration ttl) { + Assert.notNull(name, "Name must not be null!"); + Assert.notNull(key, "Key must not be null!"); + Assert.notNull(value, "Value must not be null!"); + return (byte[])this.execute(name, (connection) -> { + if (this.isLockingCacheWriter()) { + this.doLock(name, connection); + } + + Object var7; + try { + boolean put; + if (shouldExpireWithin(ttl)) { + put = connection.set(key, value, Expiration.from(ttl), SetOption.ifAbsent()); + } else { + put = connection.setNX(key, value); + } + + if (!put) { + byte[] var11 = connection.get(key); + return var11; + } + + var7 = null; + } finally { + if (this.isLockingCacheWriter()) { + this.doUnlock(name, connection); + } + + } + + return (byte[])var7; + }); + } + + @Override + public void remove(String name, byte[] key) { + Assert.notNull(name, "Name must not be null!"); + Assert.notNull(key, "Key must not be null!"); + String keyString = new String(key); + log.info("redis remove key:" + keyString); + String keyIsAll = "*"; + if(keyString!=null && keyString.endsWith(keyIsAll)){ + execute(name, connection -> { + // 获取某个前缀所拥有的所有的键,某个前缀开头,后面肯定是* + Set keys = connection.keys(key); + int delNum = 0; + for (byte[] keyByte : keys) { + delNum += connection.del(keyByte); + } + return delNum; + }); + }else{ + this.execute(name, (connection) -> { + return connection.del(new byte[][]{key}); + }); + } + } + + @Override + public void clean(String name, byte[] pattern) { + Assert.notNull(name, "Name must not be null!"); + Assert.notNull(pattern, "Pattern must not be null!"); + this.execute(name, (connection) -> { + boolean wasLocked = false; + + try { + if (this.isLockingCacheWriter()) { + this.doLock(name, connection); + wasLocked = true; + } + + byte[][] keys = (byte[][])((Set)Optional.ofNullable(connection.keys(pattern)).orElse(Collections.emptySet())).toArray(new byte[0][]); + if (keys.length > 0) { + connection.del(keys); + } + } finally { + if (wasLocked && this.isLockingCacheWriter()) { + this.doUnlock(name, connection); + } + + } + + return "OK"; + }); + } + + void lock(String name) { + this.execute(name, (connection) -> { + return this.doLock(name, connection); + }); + } + + void unlock(String name) { + this.executeLockFree((connection) -> { + this.doUnlock(name, connection); + }); + } + + private Boolean doLock(String name, RedisConnection connection) { + return connection.setNX(createCacheLockKey(name), new byte[0]); + } + + private Long doUnlock(String name, RedisConnection connection) { + return connection.del(new byte[][]{createCacheLockKey(name)}); + } + + boolean doCheckLock(String name, RedisConnection connection) { + return connection.exists(createCacheLockKey(name)); + } + + private boolean isLockingCacheWriter() { + return !this.sleepTime.isZero() && !this.sleepTime.isNegative(); + } + + private T execute(String name, Function callback) { + RedisConnection connection = this.connectionFactory.getConnection(); + + try { + this.checkAndPotentiallyWaitUntilUnlocked(name, connection); + return callback.apply(connection); + } finally { + connection.close(); + } + + } + + private void executeLockFree(Consumer callback) { + RedisConnection connection = this.connectionFactory.getConnection(); + + try { + callback.accept(connection); + } finally { + connection.close(); + } + + } + + private void checkAndPotentiallyWaitUntilUnlocked(String name, RedisConnection connection) { + if (this.isLockingCacheWriter()) { + try { + while(this.doCheckLock(name, connection)) { + Thread.sleep(this.sleepTime.toMillis()); + } + + } catch (InterruptedException var4) { + Thread.currentThread().interrupt(); + throw new PessimisticLockingFailureException(String.format("Interrupted while waiting to unlock cache %s", name), var4); + } + } + } + + private static boolean shouldExpireWithin(@Nullable Duration ttl) { + return ttl != null && !ttl.isZero() && !ttl.isNegative(); + } + + private static byte[] createCacheLockKey(String name) { + return (name + "~lock").getBytes(StandardCharsets.UTF_8); + } + + //update-begin-author:zyf date:20220216 for:升级springboot版本到2.4.0+以后需要实现的方法* + private final CacheStatisticsCollector statistics = CacheStatisticsCollector.create(); + @Override + public CacheStatistics getCacheStatistics(String cacheName) { + return statistics.getCacheStatistics(cacheName); + } + + @Override + public void clearStatistics(String name) { + + } + + @Override + public RedisCacheWriter withStatisticsCollector(CacheStatisticsCollector cacheStatisticsCollector) { + return null; + } + //update-begin-author:zyf date:20220216 for:升级springboot版本到2.4.0+以后需要实现的方法* +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/TokenUtils.java b/digital-system/src/main/java/digital/system/jeecg/group/util/TokenUtils.java new file mode 100644 index 0000000..afd4aad --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/TokenUtils.java @@ -0,0 +1,123 @@ +//package digital.system.jeecg.group.util; +// +//import digital.base.constant.CommonConstant; +//import digital.base.vo.LoginUser; +//import digital.system.jeecg.group.CommonAPI; +//import digital.util.exception.JeecgBoot401Exception; +//import digital.util.util.JeecgRedisUtil; +//import digital.util.util.JwtUtil; +//import digital.util.util.oConvertUtils; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.StringUtils; +// +//import javax.servlet.http.HttpServletRequest; +// +///** +// * @Author scott +// * @Date 2019/9/23 14:12 +// * @Description: 编程校验token有效性 +// */ +//@Slf4j +//public class TokenUtils { +// +// /** +// * 获取 request 里传递的 token +// * +// * @param request +// * @return +// */ +// public static String getTokenByRequest(HttpServletRequest request) { +// String token = request.getParameter("token"); +// if (token == null) { +// token = request.getHeader("X-Access-Token"); +// } +// return token; +// } +// +// /** +// * 验证Token +// */ +// public static boolean verifyToken(HttpServletRequest request, CommonAPI commonApi, JeecgRedisUtil jeecgRedisUtil) { +// log.debug(" -- url --" + request.getRequestURL()); +// String token = getTokenByRequest(request); +// return TokenUtils.verifyToken(token, commonApi, jeecgRedisUtil); +// } +// +// /** +// * 验证Token +// */ +// public static boolean verifyToken(String token, CommonAPI commonApi, JeecgRedisUtil jeecgRedisUtil) { +// if (StringUtils.isBlank(token)) { +// throw new JeecgBoot401Exception("token不能为空!"); +// } +// +// // 解密获得username,用于和数据库进行对比 +// String username = JwtUtil.getUsername(token); +// if (username == null) { +// throw new JeecgBoot401Exception("token非法无效!"); +// } +// +// // 查询用户信息 +// LoginUser user = TokenUtils.getLoginUser(username, commonApi, jeecgRedisUtil); +// //LoginUser user = commonApi.getUserByName(username); +// if (user == null) { +// +// +// throw new JeecgBoot401Exception("用户不存在!"); +// } +// // 判断用户状态 +// if (user.getStatus() != 1) { +// throw new JeecgBoot401Exception("账号已被锁定,请联系管理员!"); +// } +// // 校验token是否超时失效 & 或者账号密码是否错误 +// if (!jwtTokenRefresh(token, username, user.getPassword(), jeecgRedisUtil)) { +// throw new JeecgBoot401Exception(CommonConstant.TOKEN_IS_INVALID_MSG); +// } +// return true; +// } +// +// /** +// * 刷新token(保证用户在线操作不掉线) +// * +// * @param token +// * @param userName +// * @param passWord +// * @param jeecgRedisUtil +// * @return +// */ +// private static boolean jwtTokenRefresh(String token, String userName, String passWord, JeecgRedisUtil jeecgRedisUtil) { +// String cacheToken = oConvertUtils.getString(jeecgRedisUtil.get(CommonConstant.PREFIX_USER_TOKEN + token)); +// if (oConvertUtils.isNotEmpty(cacheToken)) { +// // 校验token有效性 +// if (!JwtUtil.verify(cacheToken, userName, passWord)) { +// String newAuthorization = JwtUtil.sign(userName, passWord); +// // 设置Toekn缓存有效时间 +// jeecgRedisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, newAuthorization); +// jeecgRedisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); +// } +// return true; +// } +// return false; +// } +// +// /** +// * 获取登录用户 +// * +// * @param commonApi +// * @param username +// * @return +// */ +// public static LoginUser getLoginUser(String username, CommonAPI commonApi, JeecgRedisUtil jeecgRedisUtil) { +//// LoginUser loginUser = null; +//// String loginUserKey = CacheConstant.SYS_USERS_CACHE + "::" + username; +//// if(jeecgRedisUtil.hasKey(loginUserKey)){ +//// loginUser = (LoginUser) jeecgRedisUtil.get(loginUserKey); +//// }else{ +//// // 查询用户信息 +//// loginUser = commonApi.getUserByName(username); +//// } +// log.info("====================getLoginUser======================"); +// LoginUser loginUser = commonApi.getUserByName(username); +// return loginUser; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/AutoLogAspect.java b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/AutoLogAspect.java new file mode 100644 index 0000000..6733d27 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/AutoLogAspect.java @@ -0,0 +1,296 @@ +package digital.system.jeecg.group.util.aspect; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.serializer.PropertyFilter; +import digital.base.annotation.AutoLog; +import digital.base.constant.CommonConstant; +import digital.base.enums.ModuleType; +import digital.base.enums.OperateTypeEnum; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.bean.jeecg.dto.LogDTO; +import digital.system.jeecg.group.base.service.BaseCommonService; +import digital.util.util.IpUtils; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.aspectj.lang.JoinPoint; +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.LocalVariableTableParameterNameDiscoverer; +import org.springframework.stereotype.Component; +import org.springframework.validation.BindingResult; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Date; + + +/** + * 系统日志,切面处理类 + * + * @Author scott + * @email jeecgos@163.com + * @Date 2018年1月14日 + */ +@Slf4j +@Aspect +@Component +public class AutoLogAspect { + @Resource + private BaseCommonService baseCommonService; + + @Pointcut("@annotation(digital.base.annotation.AutoLog)") + public void logPointCut() { + + } + + @Around("logPointCut()") + public Object around(ProceedingJoinPoint point) throws Throwable { + long beginTime = System.currentTimeMillis(); + //执行方法 + Object result = point.proceed(); + //执行时长(毫秒) + long time = System.currentTimeMillis() - beginTime; + + //保存日志 + saveSysLog(point, time, result); + + return result; + } + + private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + LogDTO dto = new LogDTO(); + AutoLog syslog = method.getAnnotation(AutoLog.class); + if(syslog != null){ + //update-begin-author:taoyan date: + String content = syslog.value(); + if(syslog.module()== ModuleType.ONLINE){ + content = getOnlineLogContent(obj, content); + } + //注解上的描述,操作日志内容 + dto.setLogType(syslog.logType()); + dto.setLogContent(content); + } + + //请求的方法名 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = signature.getName(); + dto.setMethod(className + "." + methodName + "()"); + + + //设置操作类型 + if (CommonConstant.LOG_TYPE_2 == dto.getLogType()) { + dto.setOperateType(getOperateType(methodName, syslog.operateType())); + } + + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //请求的参数 + dto.setRequestParam(getReqestParams(request,joinPoint)); + //设置IP地址 + dto.setIp(IpUtils.getIpAddr(request)); + //获取登录用户信息 + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + if (sysUser != null) { + dto.setUserId(sysUser.getId()); + dto.setUsername(sysUser.getUsername()); + } + String taskId = (String) request.getAttribute("taskId"); + dto.setUserId(taskId); + //耗时 + dto.setCostTime(time); + dto.setAppKey(request.getHeader("appKey")); + dto.setCreateTime(new Date()); + //返回结果 + String content = ""; + if (Result.class.isInstance(obj)) { + Result res = (Result) obj; + Object result = res.getResult(); + String message = res.getMessage(); + if (res.isSuccess()) { + content += "操作成功" + " message =" + message + " result= " + result; + } else { + content += "操作失败" + " message =" + message + " result= " + result; + } + } + dto.setResult(content); + //保存系统日志 + baseCommonService.addLog(dto); + //给飞书发调用消息 + try { + FeiShuUtils feiShuUtils = new FeiShuUtils(); + feiShuUtils.sendWebhookMes(dto); + if ("submitContactInfo".equals(methodName)) { + String requestParam = dto.getRequestParam(); + JSONArray jsonArray = JSONArray.parseArray(requestParam); + JSONObject jsonObject = jsonArray.getJSONObject(0); + String phone = jsonObject.getString("phone"); + String name = jsonObject.getString("name"); + String company = jsonObject.getString("company"); + String description = jsonObject.getString("description"); + String companyContent = "姓名:" + name + " 手机号:" + phone + " 公司:" + company + " 需求描述:" + description; + ContactFeiShuUtils contactFeiShuUtils = new ContactFeiShuUtils(); + contactFeiShuUtils.sendWebhookMes(companyContent); + } + } catch (IOException e) { + log.info("给飞书发调用消息 :" + e.getMessage()); + } + + } + + + /** + * 获取操作类型 + */ + private int getOperateType(String methodName,int operateType) { + if (operateType > 0) { + return operateType; + } + //update-begin---author:wangshuai ---date:20220331 for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------ + return OperateTypeEnum.getTypeByMethodName(methodName); + //update-end---author:wangshuai ---date:20220331 for:阿里云代码扫描规范(不允许任何魔法值出现在代码中)------------ + } + + /** + * @Description: 获取请求参数 + * @author: scott + * @date: 2020/4/16 0:10 + * @param request: request + * @param joinPoint: joinPoint + * @Return: java.lang.String + */ + private String getReqestParams(HttpServletRequest request, JoinPoint joinPoint) { + String httpMethod = request.getMethod(); + String params = ""; + if (CommonConstant.HTTP_POST.equals(httpMethod) || CommonConstant.HTTP_PUT.equals(httpMethod) || CommonConstant.HTTP_PATCH.equals(httpMethod)) { + Object[] paramsArray = joinPoint.getArgs(); + // java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false) + // https://my.oschina.net/mengzhang6/blog/2395893 + Object[] arguments = new Object[paramsArray.length]; + for (int i = 0; i < paramsArray.length; i++) { + log.info("paramsArray=="+paramsArray[i]); + if (paramsArray[i] instanceof BindingResult || paramsArray[i] instanceof ServletRequest || paramsArray[i] instanceof ServletResponse || paramsArray[i] instanceof MultipartFile) { + //ServletRequest不能序列化,从入参里排除,否则报异常:java.lang.IllegalStateException: It is illegal to call this method if the current request is not in asynchronous mode (i.e. isAsyncStarted() returns false) + //ServletResponse不能序列化 从入参里排除,否则报异常:java.lang.IllegalStateException: getOutputStream() has already been called for this response + continue; + } + arguments[i] = paramsArray[i]; + } + //update-begin-author:taoyan date:20200724 for:日志数据太长的直接过滤掉 + PropertyFilter profilter = new PropertyFilter() { + @Override + public boolean apply(Object o, String name, Object value) { +// int length = 500; +// if(value!=null && value.toString().length()>length){ +// return false; +// } + return true; + } + }; + params = JSONObject.toJSONString(arguments, profilter); + //update-end-author:taoyan date:20200724 for:日志数据太长的直接过滤掉 + } else { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + // 请求的方法参数值 + Object[] args = joinPoint.getArgs(); + // 请求的方法参数名称 + LocalVariableTableParameterNameDiscoverer u = new LocalVariableTableParameterNameDiscoverer(); + String[] paramNames = u.getParameterNames(method); + if (args != null && paramNames != null) { + for (int i = 0; i < args.length; i++) { + params += " " + paramNames[i] + ": " + args[i]; + } + } + } + return params; + } + + /** + * online日志内容拼接 + * @param obj + * @param content + * @return + */ + private String getOnlineLogContent(Object obj, String content){ + if (Result.class.isInstance(obj)){ + Result res = (Result)obj; + String msg = res.getMessage(); + String tableName = res.getOnlTable(); + if(oConvertUtils.isNotEmpty(tableName)){ + content+=",表名:"+tableName; + } + if(res.isSuccess()){ + content+= ","+(oConvertUtils.isEmpty(msg)?"操作成功":msg); + }else{ + content+= ","+(oConvertUtils.isEmpty(msg)?"操作失败":msg); + } + } + return content; + } + + + /* private void saveSysLog(ProceedingJoinPoint joinPoint, long time, Object obj) { + MethodSignature signature = (MethodSignature) joinPoint.getSignature(); + Method method = signature.getMethod(); + + SysLog sysLog = new SysLog(); + AutoLog syslog = method.getAnnotation(AutoLog.class); + if(syslog != null){ + //update-begin-author:taoyan date: + String content = syslog.value(); + if(syslog.module()== ModuleType.ONLINE){ + content = getOnlineLogContent(obj, content); + } + //注解上的描述,操作日志内容 + sysLog.setLogContent(content); + sysLog.setLogType(syslog.logType()); + } + + //请求的方法名 + String className = joinPoint.getTarget().getClass().getName(); + String methodName = signature.getName(); + sysLog.setMethod(className + "." + methodName + "()"); + + + //设置操作类型 + if (sysLog.getLogType() == CommonConstant.LOG_TYPE_2) { + sysLog.setOperateType(getOperateType(methodName, syslog.operateType())); + } + + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //请求的参数 + sysLog.setRequestParam(getReqestParams(request,joinPoint)); + + //设置IP地址 + sysLog.setIp(IPUtils.getIpAddr(request)); + + //获取登录用户信息 + LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal(); + if(sysUser!=null){ + sysLog.setUserid(sysUser.getUsername()); + sysLog.setUsername(sysUser.getRealname()); + + } + //耗时 + sysLog.setCostTime(time); + sysLog.setCreateTime(new Date()); + //保存系统日志 + sysLogService.save(sysLog); + }*/ +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/ContactFeiShuUtils.java b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/ContactFeiShuUtils.java new file mode 100644 index 0000000..ae9dac0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/ContactFeiShuUtils.java @@ -0,0 +1,37 @@ +package digital.system.jeecg.group.util.aspect; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; + +import java.io.IOException; + +@Slf4j +public class ContactFeiShuUtils { + + public static void main(String[] args) throws IOException { +// FeiShuUtils feiShuUtils = new FeiShuUtils(); +// feiShuUtils.sendWebshookMes(); + } + + public void sendWebhookMes(String dto) throws IOException { + OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + MediaType mediaType = MediaType.parse("application/json"); + JSONObject content = new JSONObject(); + content.put("msg_type", "text"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("text", dto.toString()); + content.put("content", jsonObject); +// log.info("发送内容 :" + content); + RequestBody body = RequestBody.create(mediaType, content.toJSONString()); + Request request = new Request.Builder() + .url("https://open.feishu.cn/open-apis/bot/v2/hook/79d931ff-f30b-4ad8-861c-2b5979931956") + .method("POST", body) + .addHeader("Content-Type", "application/json") + .build(); + Response response = client.newCall(request).execute(); + log.info("sendMes to 飞书 :" + response); + response.close(); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/DictAspect.java b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/DictAspect.java new file mode 100644 index 0000000..04660db --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/DictAspect.java @@ -0,0 +1,454 @@ +//package digital.system.jeecg.group.util.aspect; +//import cn.hutool.core.bean.BeanUtil; +//import cn.hutool.core.util.ObjectUtil; +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.fasterxml.jackson.annotation.JsonFormat; +//import com.fasterxml.jackson.core.JsonProcessingException; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import lombok.extern.slf4j.Slf4j; +//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.beans.factory.annotation.Autowired; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.stereotype.Component; +//import org.springframework.util.StringUtils; +//import digital.base.annotation.Dict; +//import digital.base.constant.CommonConstant; +//import digital.base.vo.Result; +//import digital.bean.jeecg.vo.DictModel; +//import digital.system.jeecg.group.CommonAPI; +//import digital.util.util.oConvertUtils; +// +//import java.lang.reflect.Field; +//import java.text.SimpleDateFormat; +//import java.util.*; +//import java.util.regex.Pattern; +//import java.util.stream.Collectors; +// +///** +// * 字典aop类 +// * @author: dangzhenghui +// * @version: 1.0 +// */ +//@Aspect +//@Component +//@Slf4j +//public class DictAspect { +// +// @Autowired +// private CommonAPI commonAPI; +// @Autowired +// public RedisTemplate redisTemplate; +// +// private Pattern pattern = Pattern.compile("\\$\\{\\S+\\}"); +// // 定义切点Pointcut +// @Pointcut("execution(public * *..*.*Controller.*(..)) || @annotation(digital.base.annotation.AutoDict)") +// public void excudeService() { +// } +// +// @Around("excudeService()") +// public Object doAround(ProceedingJoinPoint pjp) throws Throwable { +// long time1=System.currentTimeMillis(); +// Object result = pjp.proceed(); +// long time2=System.currentTimeMillis(); +// log.debug("获取JSON数据 耗时:"+(time2-time1)+"ms"); +// long start=System.currentTimeMillis(); +// this.parseDictText(result); +// long end=System.currentTimeMillis(); +// log.debug("注入字典到JSON数据 耗时"+(end-start)+"ms"); +// return result; +// } +// +// /** +// * 本方法针对返回对象为Result 的IPage的分页列表数据进行动态字典注入 +// * 字典注入实现 通过对实体类添加注解@dict 来标识需要的字典内容,字典分为单字典code即可 ,table字典 code table text配合使用与原来jeecg的用法相同 +// * 示例为SysUser 字段为sex 添加了注解@Dict(dicCode = "sex") 会在字典服务立马查出来对应的text 然后在请求list的时候将这个字典text,已字段名称加_dictText形式返回到前端 +// * 例输入当前返回值的就会多出一个sex_dictText字段 +// * { +// * sex:1, +// * sex_dictText:"男" +// * } +// * 前端直接取值sext_dictText在table里面无需再进行前端的字典转换了 +// * customRender:function (text) { +// * if(text==1){ +// * return "男"; +// * }else if(text==2){ +// * return "女"; +// * }else{ +// * return text; +// * } +// * } +// * 目前vue是这么进行字典渲染到table上的多了就很麻烦了 这个直接在服务端渲染完成前端可以直接用 +// * @param result +// */ +// private void parseDictText(Object result) throws JsonProcessingException { +// if (result instanceof Result) { +// List records = null; +// +// List items = new ArrayList<>(); +// //step.1 筛选出加了 Dict 注解的字段列表 +// List dictFieldList = new ArrayList<>(); +// // 字典数据列表, key = 字典code,value=数据列表 +// Map> dataListMap = new HashMap<>(); +// if (((Result) result).getResult() instanceof IPage) { +// records = ((IPage) ((Result) result).getResult()).getRecords(); +// +// } else if (((Result) result).getResult() instanceof List) { +// records = (List)((Result) result).getResult(); +// } +// if(ObjectUtil.isNotEmpty(((Result) result).getResult())) { +// if (Objects.nonNull(records) && !records.isEmpty()) { +// Object record = records.get(0); +// if (!(record.getClass().getName().contains("java.lang") || record.getClass().getName().contains("java.util") || record.getClass().getName().contains("java.math"))) { +// handleList(records, items, dictFieldList, dataListMap); +// if (((Result) result).getResult() instanceof IPage) { +// ((IPage) ((Result) result).getResult()).setRecords(items); +// +// } else if (((Result) result).getResult() instanceof List) { +// ((Result) result).setResult(items); +// } +// } else { +// ((Result) result).setResult(records); +// } +// } else if (!(((Result) result).getResult().getClass().getName().contains("java.lang") || ((Result) result).getResult().getClass().getName().contains("java.util") || ((Result) result).getResult().getClass().getName().contains("java.math"))) { +// ArrayList arrayList = new ArrayList<>(); +// arrayList.add(((Result) result).getResult()); +// handleList(arrayList, items, dictFieldList, dataListMap); +// ((Result) result).setResult(items.get(0)); +// }else if (!(((Result) result).getResult().getClass().getClass().getName().contains("java.lang") || ((Result) result).getResult().getClass().getClass().getName().contains("java.util") || ((Result) result).getResult().getClass().getClass().getName().contains("java.math"))) { +// ArrayList arrayList = new ArrayList<>(); +// arrayList.add(((Result) result).getResult()); +// handleList(arrayList, items, dictFieldList, dataListMap); +// ((Result) result).setResult(items.get(0)); +// } +// } +// return; +// } +// } +// +// private void handleList(List records, List items, List dictFieldList, Map> dataListMap) throws JsonProcessingException { +// for (Object record : records) { +// ObjectMapper mapper = new ObjectMapper(); +// String json = "{}"; +// try { +// //解决@JsonFormat注解解析不了的问题详见SysAnnouncement类的@JsonFormat +// json = mapper.writeValueAsString(record); +// } catch (JsonProcessingException e) { +// log.error("json解析失败" + e.getMessage(), e); +// break; +// } +//// if (record.getClass().getName().contains("java.lang")){ +//// mapper.readValue(json, String.class); +//// items.add(JSONObject.parseObject((String) record)); +//// continue; +//// } +// JSONObject item = JSONObject.parseObject(json); +// //update-begin--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ +// //for (Field field : record.getClass().getDeclaredFields()) { +// // 遍历所有字段,把字典Code取出来,放到 map 里 +// for (Field field : oConvertUtils.getAllFields(record)) { +// Object value = item.get(field.getName()); +// if (value == null || (value instanceof String && oConvertUtils.isEmpty(value))) { +// continue; +// } +// if (field.getType().getName().equals("java.util.List")) { +// List list = (List) value; +// if (list != null && list.size() >0 ){ +// Object ob = list.get(0); +// if (ob.getClass().getName().contains("java.lang")){ +// continue; +// } +// } +// List itemsChildren = new ArrayList<>(); +// List dictFieldListChildren = new ArrayList<>(); +// // 字典数据列表, key = 字典code,value=数据列表 +// Map> dataListMapChildren = new HashMap<>(); +//// private void hanldeList(List records, List items, List dictFieldList, Map> dataListMap) +// handleList((List) BeanUtil.getFieldValue(record, field.getName()), itemsChildren, dictFieldListChildren, dataListMapChildren); +// item.put(field.getName(), itemsChildren); +// } else if(item.get(field.getName()) instanceof JSONObject){ +// List itemsObject = new ArrayList<>(); +// //step.1 筛选出加了 Dict 注解的字段列表 +// List dictFieldListObject = new ArrayList<>(); +// // 字典数据列表, key = 字典code,value=数据列表 +// Map> dataListMapObject = new HashMap<>(); +// ArrayList arrayList = new ArrayList<>(); +// arrayList.add( BeanUtil.getFieldValue(record,field.getName())); +// handleList(arrayList, itemsObject, dictFieldListObject, dataListMapObject); +// item.put(field.getName(), itemsObject.get(0)); +// }else { +// handleField(dictFieldList, dataListMap, item, field, value.toString()); +// } +// +// } +// items.add(item); +// } +// +// //step.2 调用翻译方法,一次性翻译 +// Map> translText = this.translateAllDict(dataListMap); +// +// //step.3 将翻译结果填充到返回结果里 +// for (JSONObject record : items) { +// for (Field field : dictFieldList) { +// String code = field.getAnnotation(Dict.class).dicCode(); +// String text = field.getAnnotation(Dict.class).dicText(); +// String table = field.getAnnotation(Dict.class).dictTable(); +// +// String fieldDictCode = code; +// if (!StringUtils.isEmpty(table)) { +// fieldDictCode = String.format("%s,%s,%s", table, text, code); +// } +// +// String value = record.getString(field.getName()); +// if (oConvertUtils.isNotEmpty(value)) { +// List dictModels = translText.get(fieldDictCode); +// if (dictModels == null || dictModels.size() == 0) { +// continue; +// } +// +// String textValue = this.translDictText(dictModels, value); +// log.debug(" 字典Val : " + textValue); +// log.debug(" __翻译字典字段__ " + field.getName() + CommonConstant.DICT_TEXT_SUFFIX + ": " + textValue); +// // TODO-sun 测试输出,待删 +// log.debug(" ---- dictCode: " + fieldDictCode); +// log.debug(" ---- value: " + value); +// log.debug(" ----- text: " + textValue); +// log.debug(" ---- dictModels: " + JSON.toJSONString(dictModels)); +// record.put(field.getName() + CommonConstant.DICT_TEXT_SUFFIX, textValue); +// } +// } +// } +// } +// +// private void handleField(List dictFieldList, Map> dataListMap, JSONObject item, Field field, String value) { +// //update-end--Author:scott -- Date:20190603 ----for:解决继承实体字段无法翻译问题------ +// if (field.getAnnotation(Dict.class) != null) { +// if (!dictFieldList.contains(field)) { +// dictFieldList.add(field); +// } +// String code = field.getAnnotation(Dict.class).dicCode(); +// String text = field.getAnnotation(Dict.class).dicText(); +// String table = field.getAnnotation(Dict.class).dictTable(); +// log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code); +// List dataList; +// String dictCode = code; +// if (!StringUtils.isEmpty(table)) { +// dictCode = String.format("%s,%s,%s", table, text, code); +// } +// dataList = dataListMap.computeIfAbsent(dictCode, k -> new ArrayList<>()); +// this.listAddAllDeduplicate(dataList, Arrays.asList(value.split(","))); +// } +// //date类型默认转换string格式化日期 +// if (field.getType().getName().equals("java.util.Date") && field.getAnnotation(JsonFormat.class) == null && item.get(field.getName()) != null) { +// SimpleDateFormat aDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); +// item.put(field.getName(), aDate.format(new Date((Long) item.get(field.getName())))); +// } +// } +// +// /** +// * list 去重添加 +// */ +// private void listAddAllDeduplicate(List dataList, List addList) { +// // 筛选出dataList中没有的数据 +// List filterList = addList.stream().filter(i -> !dataList.contains(i)).collect(Collectors.toList()); +// dataList.addAll(filterList); +// } +// +// /** +// * 一次性把所有的字典都翻译了 +// * 1. 所有的普通数据字典的所有数据只执行一次SQL +// * 2. 表字典相同的所有数据只执行一次SQL +// * @param dataListMap +// * @return +// */ +// private Map> translateAllDict(Map> dataListMap) { +// // 翻译后的字典文本,key=dictCode +// Map> translText = new HashMap<>(); +// // 需要翻译的数据(有些可以从redis缓存中获取,就不走数据库查询) +// List needTranslData = new ArrayList<>(); +// //step.1 先通过redis中获取缓存字典数据 +// for (String dictCode : dataListMap.keySet()) { +// List dataList = dataListMap.get(dictCode); +// if (dataList.size() == 0) { +// continue; +// } +// // 表字典需要翻译的数据 +// List needTranslDataTable = new ArrayList<>(); +// for (String s : dataList) { +// String data = s.trim(); +// if (data.length() == 0) { +// continue; //跳过循环 +// } +// if (dictCode.contains(",")) { +// String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, data); +// if (redisTemplate.hasKey(keyString)) { +// try { +// String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); +// List list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); +// list.add(new DictModel(data, text)); +// } catch (Exception e) { +// log.warn(e.getMessage()); +// } +// } else if (!needTranslDataTable.contains(data)) { +// // 去重添加 +// needTranslDataTable.add(data); +// } +// } else { +// String keyString = String.format("sys:cache:dict::%s:%s", dictCode, data); +// if (redisTemplate.hasKey(keyString)) { +// try { +// String text = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); +// List list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); +// list.add(new DictModel(data, text)); +// } catch (Exception e) { +// log.warn(e.getMessage()); +// } +// } else if (!needTranslData.contains(data)) { +// // 去重添加 +// needTranslData.add(data); +// } +// } +// +// } +// //step.2 调用数据库翻译表字典 +// if (needTranslDataTable.size() > 0) { +// String[] arr = dictCode.split(","); +// String table = arr[0], text = arr[1], code = arr[2]; +// String values = String.join(",", needTranslDataTable); +// log.info("translateDictFromTableByKeys.dictCode:" + dictCode); +// log.info("translateDictFromTableByKeys.values:" + values); +// List texts = commonAPI.translateDictFromTableByKeys(table, text, code, values); +// log.info("translateDictFromTableByKeys.result:" + texts); +// List list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); +// list.addAll(texts); +// +// // 做 redis 缓存 +// for (DictModel dict : texts) { +// String redisKey = String.format("sys:cache:dictTable::SimpleKey [%s,%s]", dictCode, dict.getValue()); +// try { +// redisTemplate.opsForValue().set(redisKey, dict.getText()); +// } catch (Exception e) { +// log.warn(e.getMessage(), e); +// } +// } +// } +// } +// +// //step.3 调用数据库进行翻译普通字典 +// if (needTranslData.size() > 0) { +// List dictCodeList = Arrays.asList(dataListMap.keySet().toArray(new String[]{})); +// // 将不包含逗号的字典code筛选出来,因为带逗号的是表字典,而不是普通的数据字典 +// List filterDictCodes = dictCodeList.stream().filter(key -> !key.contains(",")).collect(Collectors.toList()); +// String dictCodes = String.join(",", filterDictCodes); +// String values = String.join(",", needTranslData); +// log.info("translateManyDict.dictCodes:" + dictCodes); +// log.info("translateManyDict.values:" + values); +// Map> manyDict = commonAPI.translateManyDict(dictCodes, values); +// log.info("translateManyDict.result:" + manyDict); +// for (String dictCode : manyDict.keySet()) { +// List list = translText.computeIfAbsent(dictCode, k -> new ArrayList<>()); +// List newList = manyDict.get(dictCode); +// list.addAll(newList); +// +// // 做 redis 缓存 +// for (DictModel dict : newList) { +// String redisKey = String.format("sys:cache:dict::%s:%s", dictCode, dict.getValue()); +// try { +// redisTemplate.opsForValue().set(redisKey, dict.getText()); +// } catch (Exception e) { +// log.warn(e.getMessage(), e); +// } +// } +// } +// } +// return translText; +// } +// +// /** +// * 字典值替换文本 +// * +// * @param dictModels +// * @param values +// * @return +// */ +// private String translDictText(List dictModels, String values) { +// List result = new ArrayList<>(); +// +// // 允许多个逗号分隔,允许传数组对象 +// String[] splitVal = values.split(","); +// for (String val : splitVal) { +// String dictText = val; +// for (DictModel dict : dictModels) { +// if (val.equals(dict.getValue())) { +// dictText = dict.getText(); +// break; +// } +// } +// result.add(dictText); +// } +// return String.join(",", result); +// } +// +// /** +// * 翻译字典文本 +// * @param code +// * @param text +// * @param table +// * @param key +// * @return +// */ +// @Deprecated +// private String translateDictValue(String code, String text, String table, String key) { +// if(oConvertUtils.isEmpty(key)) { +// return null; +// } +// StringBuffer textValue=new StringBuffer(); +// String[] keys = key.split(","); +// for (String k : keys) { +// String tmpValue = null; +// log.debug(" 字典 key : "+ k); +// if (k.trim().length() == 0) { +// continue; //跳过循环 +// } +// //update-begin--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题----- +// if (!StringUtils.isEmpty(table)){ +// log.info("--DictAspect------dicTable="+ table+" ,dicText= "+text+" ,dicCode="+code); +// String keyString = String.format("sys:cache:dictTable::SimpleKey [%s,%s,%s,%s]",table,text,code,k.trim()); +// if (redisTemplate.hasKey(keyString)){ +// try { +// tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); +// } catch (Exception e) { +// log.warn(e.getMessage()); +// } +// }else { +// tmpValue= commonAPI.translateDictFromTable(table,text,code,k.trim()); +// } +// }else { +// String keyString = String.format("sys:cache:dict::%s:%s",code,k.trim()); +// if (redisTemplate.hasKey(keyString)){ +// try { +// tmpValue = oConvertUtils.getString(redisTemplate.opsForValue().get(keyString)); +// } catch (Exception e) { +// log.warn(e.getMessage()); +// } +// }else { +// tmpValue = commonAPI.translateDict(code, k.trim()); +// } +// } +// //update-end--Author:scott -- Date:20210531 ----for: !56 优化微服务应用下存在表字段需要字典翻译时加载缓慢问题----- +// +// if (tmpValue != null) { +// if (!"".equals(textValue.toString())) { +// textValue.append(","); +// } +// textValue.append(tmpValue); +// } +// +// } +// return textValue.toString(); +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/FeiShuUtils.java b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/FeiShuUtils.java new file mode 100644 index 0000000..e5a7bf0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/FeiShuUtils.java @@ -0,0 +1,38 @@ +package digital.system.jeecg.group.util.aspect; + +import com.alibaba.fastjson.JSONObject; +import digital.bean.jeecg.dto.LogDTO; +import lombok.extern.slf4j.Slf4j; +import okhttp3.*; + +import java.io.IOException; + +@Slf4j +public class FeiShuUtils { + + public static void main(String[] args) throws IOException { +// FeiShuUtils feiShuUtils = new FeiShuUtils(); +// feiShuUtils.sendWebshookMes(); + } + + public void sendWebhookMes(LogDTO dto) throws IOException { + OkHttpClient client = new OkHttpClient().newBuilder() + .build(); + MediaType mediaType = MediaType.parse("application/json"); + JSONObject content = new JSONObject(); + content.put("msg_type", "text"); + JSONObject jsonObject = new JSONObject(); + jsonObject.put("text", dto.toString()); + content.put("content", jsonObject); +// log.info("发送内容 :" + content); + RequestBody body = RequestBody.create(mediaType, content.toJSONString()); + Request request = new Request.Builder() + .url("https://open.feishu.cn/open-apis/bot/v2/hook/69de5c32-67cc-4c10-ac5d-ce10a7e03ead") + .method("POST", body) + .addHeader("Content-Type", "application/json") + .build(); + Response response = client.newCall(request).execute(); + log.info("sendMes to 飞书 :" + response); + response.close(); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/PermissionDataAspect.java b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/PermissionDataAspect.java new file mode 100644 index 0000000..f41253d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/aspect/PermissionDataAspect.java @@ -0,0 +1,135 @@ +package digital.system.jeecg.group.util.aspect; + +import digital.system.jeecg.group.CommonAPI; +import digital.system.jeecg.group.query.QueryRuleEnum; +import lombok.extern.slf4j.Slf4j; +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.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; +import digital.base.annotation.PermissionData; +import digital.base.constant.CommonConstant; +import digital.base.constant.SymbolConstant; +import digital.base.enums.UrlMatchEnum; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.util.util.*; + +import javax.servlet.http.HttpServletRequest; +import java.lang.reflect.Method; +import java.util.List; + +/** + * 数据权限切面处理类 + * 当被请求的方法有注解PermissionData时,会在往当前request中写入数据权限信息 + * @Date 2019年4月10日 + * @Version: 1.0 + * @author: smcp + */ +@Aspect +@Component +@Slf4j +public class PermissionDataAspect { + @Lazy + @Autowired + private CommonAPI commonApi; + + @Pointcut("@annotation(digital.base.annotation.PermissionData)") + public void pointCut() { + + } + + @Around("pointCut()") + public Object arround(ProceedingJoinPoint point) throws Throwable{ + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + MethodSignature signature = (MethodSignature) point.getSignature(); + Method method = signature.getMethod(); + PermissionData pd = method.getAnnotation(PermissionData.class); + String component = pd.pageComponent(); + String requestMethod = request.getMethod(); + String requestPath = request.getRequestURI().substring(request.getContextPath().length()); + requestPath = filterUrl(requestPath); + //update-begin-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效 + //先判断是否online报表请求 + // TODO 参数顺序调整有隐患 + if(requestPath.indexOf(UrlMatchEnum.CGREPORT_DATA.getMatchUrl())>=0){ + // 获取地址栏参数 + String urlParamString = request.getParameter(CommonConstant.ONL_REP_URL_PARAM_STR); + if(oConvertUtils.isNotEmpty(urlParamString)){ + requestPath+="?"+urlParamString; + } + } + //update-end-author:taoyan date:20211027 for:JTC-132【online报表权限】online报表带参数的菜单配置数据权限无效 + log.info("拦截请求 >> {} ; 请求类型 >> {} . ", requestPath, requestMethod); + String username = JwtUtil.getUserNameByToken(request); + //查询数据权限信息 + //TODO 微服务情况下也得支持缓存机制 + List dataRules = commonApi.queryPermissionDataRule(component, requestPath, username); + if(dataRules!=null && dataRules.size()>0) { + //临时存储 + JeecgDataAutorUtils.installDataSearchConditon(request, dataRules); + //TODO 微服务情况下也得支持缓存机制 + SysUserCacheInfo userinfo = commonApi.getCacheUser(username); + JeecgDataAutorUtils.installUserInfo(request, userinfo); + } + return point.proceed(); + } + + private String filterUrl(String requestPath){ + String url = ""; + if(oConvertUtils.isNotEmpty(requestPath)){ + url = requestPath.replace("\\", "/"); + url = url.replace("//", "/"); + if(url.indexOf(SymbolConstant.DOUBLE_SLASH)>=0){ + url = filterUrl(url); + } + /*if(url.startsWith("/")){ + url=url.substring(1); + }*/ + } + return url; + } + + /** + * 获取请求地址 + * @param request + * @return + */ + @Deprecated + private String getJgAuthRequsetPath(HttpServletRequest request) { + String queryString = request.getQueryString(); + String requestPath = request.getRequestURI(); + if(oConvertUtils.isNotEmpty(queryString)){ + requestPath += "?" + queryString; + } + // 去掉其他参数(保留一个参数) 例如:loginController.do?login + if (requestPath.indexOf(SymbolConstant.AND) > -1) { + requestPath = requestPath.substring(0, requestPath.indexOf("&")); + } + if(requestPath.indexOf(QueryRuleEnum.EQ.getValue())!=-1){ + if(requestPath.indexOf(CommonConstant.SPOT_DO)!=-1){ + requestPath = requestPath.substring(0,requestPath.indexOf(".do")+3); + }else{ + requestPath = requestPath.substring(0,requestPath.indexOf("?")); + } + } + // 去掉项目路径 + requestPath = requestPath.substring(request.getContextPath().length() + 1); + return filterUrl(requestPath); + } + + @Deprecated + private boolean moHuContain(List list,String key){ + for(String str : list){ + if(key.contains(str)){ + return true; + } + } + return false; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/db/DataSourceCachePool.java b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DataSourceCachePool.java new file mode 100644 index 0000000..f602907 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DataSourceCachePool.java @@ -0,0 +1,93 @@ +//package digital.system.jeecg.group.util.db; +// +//import com.alibaba.druid.pool.DruidDataSource; +//import org.springframework.data.redis.core.RedisTemplate; +//import digital.base.constant.CacheConstant; +//import digital.bean.jeecg.vo.DynamicDataSourceModel; +//import digital.system.jeecg.group.CommonAPI; +//import digital.util.util.SpringContextUtils; +// +//import java.util.HashMap; +//import java.util.Map; +// +// +///** +// * 数据源缓存池 +// * @author: smcp +// */ +//public class DataSourceCachePool { +// /** 数据源连接池缓存【本地 class缓存 - 不支持分布式】 */ +// private static Map dbSources = new HashMap<>(); +// private static RedisTemplate redisTemplate; +// +// private static RedisTemplate getRedisTemplate() { +// if (redisTemplate == null) { +// redisTemplate = (RedisTemplate) SpringContextUtils.getBean("redisTemplate"); +// } +// return redisTemplate; +// } +// +// /** +// * 获取多数据源缓存 +// * +// * @param dbKey +// * @return +// */ +// public static DynamicDataSourceModel getCacheDynamicDataSourceModel(String dbKey) { +// String redisCacheKey = CacheConstant.SYS_DYNAMICDB_CACHE + dbKey; +// if (getRedisTemplate().hasKey(redisCacheKey)) { +// return (DynamicDataSourceModel) getRedisTemplate().opsForValue().get(redisCacheKey); +// } +// CommonAPI commonApi = SpringContextUtils.getBean(CommonAPI.class); +// DynamicDataSourceModel dbSource = commonApi.getDynamicDbSourceByCode(dbKey); +// if (dbSource != null) { +// getRedisTemplate().opsForValue().set(redisCacheKey, dbSource); +// } +// return dbSource; +// } +// +// public static DruidDataSource getCacheBasicDataSource(String dbKey) { +// return dbSources.get(dbKey); +// } +// +// /** +// * put 数据源缓存 +// * +// * @param dbKey +// * @param db +// */ +// public static void putCacheBasicDataSource(String dbKey, DruidDataSource db) { +// dbSources.put(dbKey, db); +// } +// +// /** +// * 清空数据源缓存 +// */ +// public static void cleanAllCache() { +// //关闭数据源连接 +// for(Map.Entry entry : dbSources.entrySet()){ +// String dbkey = entry.getKey(); +// DruidDataSource druidDataSource = entry.getValue(); +// if(druidDataSource!=null && druidDataSource.isEnable()){ +// druidDataSource.close(); +// } +// //清空redis缓存 +// getRedisTemplate().delete(CacheConstant.SYS_DYNAMICDB_CACHE + dbkey); +// } +// //清空缓存 +// dbSources.clear(); +// } +// +// public static void removeCache(String dbKey) { +// //关闭数据源连接 +// DruidDataSource druidDataSource = dbSources.get(dbKey); +// if(druidDataSource!=null && druidDataSource.isEnable()){ +// druidDataSource.close(); +// } +// //清空redis缓存 +// getRedisTemplate().delete(CacheConstant.SYS_DYNAMICDB_CACHE + dbKey); +// //清空缓存 +// dbSources.remove(dbKey); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/db/DbTypeUtils.java b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DbTypeUtils.java new file mode 100644 index 0000000..da02985 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DbTypeUtils.java @@ -0,0 +1,122 @@ +package digital.system.jeecg.group.util.db; + +import com.baomidou.mybatisplus.annotation.DbType; +import digital.base.constant.DataBaseConstant; + +import java.util.HashMap; +import java.util.Map; + +/** + * 数据库类型判断 + * 【有些数据库引擎是一样的,以达到复用目的】 + * @author: smcp + */ +public class DbTypeUtils { + + public static Map dialectMap = new HashMap(); + static{ + dialectMap.put("mysql", "org.hibernate.dialect.MySQL5InnoDBDialect"); + // mariadb数据库 1 -- + dialectMap.put("mariadb", "org.hibernate.dialect.MariaDBDialect"); + //oracle数据库 1 + dialectMap.put("oracle", "org.hibernate.dialect.OracleDialect"); + // TODO 没找到不确定 + dialectMap.put("oracle12c", "org.hibernate.dialect.OracleDialect"); + // db2数据库 1xx + dialectMap.put("db2", "org.hibernate.dialect.DB2390Dialect"); + // H2数据库 + dialectMap.put("h2", "org.hibernate.dialect.HSQLDialect"); + // HSQL数据库 1 + dialectMap.put("hsql", "org.hibernate.dialect.HSQLDialect"); + //SQLite数据库 应用平台mobile + dialectMap.put("sqlite", "org.jeecg.modules.online.config.dialect.SQLiteDialect"); + //PostgreSQL数据库1 -- + dialectMap.put("postgresql", "org.hibernate.dialect.PostgreSQLDialect"); + dialectMap.put("sqlserver2005", "org.hibernate.dialect.SQLServer2005Dialect"); + //sqlserver数据库1 + dialectMap.put("sqlserver", "org.hibernate.dialect.SQLServerDialect"); + //达梦数据库 [国产] 1-- + dialectMap.put("dm", "org.hibernate.dialect.DmDialect"); + //虚谷数据库 + dialectMap.put("xugu", "org.hibernate.dialect.HSQLDialect"); + //人大金仓 [国产] 1 + dialectMap.put("kingbasees", "org.hibernate.dialect.PostgreSQLDialect"); + // Phoenix HBase数据库 + dialectMap.put("phoenix", "org.hibernate.dialect.HSQLDialect"); + // Gauss 数据库 + dialectMap.put("zenith", "org.hibernate.dialect.PostgreSQLDialect"); + //阿里云PolarDB + dialectMap.put("clickhouse", "org.hibernate.dialect.MySQLDialect"); + // 南大通用数据库 TODO 没找到不确定 + dialectMap.put("gbase", "org.hibernate.dialect.PostgreSQLDialect"); + //神通数据库 [国产] TODO 没找到不确定 + dialectMap.put("oscar", "org.hibernate.dialect.PostgreSQLDialect"); + //Sybase ASE 数据库 + dialectMap.put("sybase", "org.hibernate.dialect.SybaseDialect"); + dialectMap.put("oceanbase", "org.hibernate.dialect.PostgreSQLDialect"); + dialectMap.put("Firebird", "org.hibernate.dialect.FirebirdDialect"); + //瀚高数据库 + dialectMap.put("highgo", "org.hibernate.dialect.HSQLDialect"); + dialectMap.put("other", "org.hibernate.dialect.PostgreSQLDialect"); + } + + public static boolean dbTypeIsMySql(DbType dbType) { + return dbTypeIf(dbType, DbType.MYSQL, DbType.MARIADB, DbType.CLICK_HOUSE, DbType.SQLITE); + } + + public static boolean dbTypeIsOracle(DbType dbType) { + return dbTypeIf(dbType, DbType.ORACLE, DbType.ORACLE_12C, DbType.DM); + } + + public static boolean dbTypeIsSqlServer(DbType dbType) { + return dbTypeIf(dbType, DbType.SQL_SERVER, DbType.SQL_SERVER2005); + } + + public static boolean dbTypeIsPostgre(DbType dbType) { + return dbTypeIf(dbType, DbType.POSTGRE_SQL, DbType.KINGBASE_ES, DbType.GAUSS); + } + + + + /** + * 根据枚举类 获取数据库类型的字符串 + * @param dbType + * @return + */ + public static String getDbTypeString(DbType dbType){ + if(DbType.DB2.equals(dbType)){ + return DataBaseConstant.DB_TYPE_DB2; + }else if(DbType.HSQL.equals(dbType)){ + return DataBaseConstant.DB_TYPE_HSQL; + }else if(dbTypeIsOracle(dbType)){ + return DataBaseConstant.DB_TYPE_ORACLE; + }else if(dbTypeIsSqlServer(dbType)){ + return DataBaseConstant.DB_TYPE_SQLSERVER; + }else if(dbTypeIsPostgre(dbType)){ + return DataBaseConstant.DB_TYPE_POSTGRESQL; + } + return DataBaseConstant.DB_TYPE_MYSQL; + } + + /** + * 根据枚举类 获取数据库方言字符串 + * @param dbType + * @return + */ + public static String getDbDialect(DbType dbType){ + return dialectMap.get(dbType.getDb()); + } + + /** + * 判断数据库类型 + */ + public static boolean dbTypeIf(DbType dbType, DbType... correctTypes) { + for (DbType type : correctTypes) { + if (type.equals(dbType)) { + return true; + } + } + return false; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/db/DynamicDBUtil.java b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DynamicDBUtil.java new file mode 100644 index 0000000..c1ef7ed --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/db/DynamicDBUtil.java @@ -0,0 +1,342 @@ +//package digital.system.jeecg.group.util.db; +// +//import com.alibaba.druid.pool.DruidDataSource; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.ArrayUtils; +//import org.springframework.jdbc.core.JdbcTemplate; +//import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; +//import digital.bean.jeecg.vo.DynamicDataSourceModel; +//import digital.util.exception.JeecgBootException; +//import digital.util.util.ReflectHelper; +//import digital.util.util.oConvertUtils; +// +//import java.sql.SQLException; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +// +///** +// * Spring JDBC 实时数据库访问 +// * +// * @author chenguobin +// * @version 1.0 +// * @date 2014-09-05 +// */ +//@Slf4j +//public class DynamicDBUtil { +// +// /** +// * 获取数据源【最底层方法,不要随便调用】 +// * +// * @param dbSource +// * @return +// */ +// private static DruidDataSource getJdbcDataSource(final DynamicDataSourceModel dbSource) { +// DruidDataSource dataSource = new DruidDataSource(); +// +// String driverClassName = dbSource.getDbDriver(); +// String url = dbSource.getDbUrl(); +// String dbUser = dbSource.getDbUsername(); +// String dbPassword = dbSource.getDbPassword(); +// dataSource.setDriverClassName(driverClassName); +// dataSource.setUrl(url); +// //dataSource.setValidationQuery("SELECT 1 FROM DUAL"); +// dataSource.setTestWhileIdle(true); +// dataSource.setTestOnBorrow(false); +// dataSource.setTestOnReturn(false); +// dataSource.setBreakAfterAcquireFailure(true); +// dataSource.setConnectionErrorRetryAttempts(0); +// dataSource.setUsername(dbUser); +// dataSource.setMaxWait(30000); +// dataSource.setPassword(dbPassword); +// +// log.info("******************************************"); +// log.info("* *"); +// log.info("*====【"+dbSource.getCode()+"】=====Druid连接池已启用 ====*"); +// log.info("* *"); +// log.info("******************************************"); +// return dataSource; +// } +// +// /** +// * 通过 dbKey ,获取数据源 +// * +// * @param dbKey +// * @return +// */ +// public static DruidDataSource getDbSourceByDbKey(final String dbKey) { +// //获取多数据源配置 +// DynamicDataSourceModel dbSource = DataSourceCachePool.getCacheDynamicDataSourceModel(dbKey); +// //先判断缓存中是否存在数据库链接 +// DruidDataSource cacheDbSource = DataSourceCachePool.getCacheBasicDataSource(dbKey); +// if (cacheDbSource != null && !cacheDbSource.isClosed()) { +// log.debug("--------getDbSourceBydbKey------------------从缓存中获取DB连接-------------------"); +// return cacheDbSource; +// } else { +// DruidDataSource dataSource = getJdbcDataSource(dbSource); +// if(dataSource!=null && dataSource.isEnable()){ +// DataSourceCachePool.putCacheBasicDataSource(dbKey, dataSource); +// }else{ +// throw new JeecgBootException("动态数据源连接失败,dbKey:"+dbKey); +// } +// log.info("--------getDbSourceBydbKey------------------创建DB数据库连接-------------------"); +// return dataSource; +// } +// } +// +// /** +// * 关闭数据库连接池 +// * +// * @param dbKey +// * @return +// */ +// public static void closeDbKey(final String dbKey) { +// DruidDataSource dataSource = getDbSourceByDbKey(dbKey); +// try { +// if (dataSource != null && !dataSource.isClosed()) { +// dataSource.getConnection().commit(); +// dataSource.getConnection().close(); +// dataSource.close(); +// } +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } +// +// +// private static JdbcTemplate getJdbcTemplate(String dbKey) { +// DruidDataSource dataSource = getDbSourceByDbKey(dbKey); +// return new JdbcTemplate(dataSource); +// } +// +// /** +// * 根据数据源获取NamedParameterJdbcTemplate +// * @param dbKey +// * @return +// */ +// private static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate(String dbKey) { +// DruidDataSource dataSource = getDbSourceByDbKey(dbKey); +// return new NamedParameterJdbcTemplate(dataSource); +// } +// +// /** +// * Executes the SQL statement in this PreparedStatement object, +// * which must be an SQL Data Manipulation Language (DML) statement, such as INSERT, UPDATE or +// * DELETE; or an SQL statement that returns nothing, +// * such as a DDL statement. +// */ +// public static int update(final String dbKey, String sql, Object... param) { +// int effectCount; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// if (ArrayUtils.isEmpty(param)) { +// effectCount = jdbcTemplate.update(sql); +// } else { +// effectCount = jdbcTemplate.update(sql, param); +// } +// return effectCount; +// } +// +// /** +// * 支持miniDao语法操作的Update +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// public static int updateByHash(final String dbKey, String sql, HashMap data) { +// int effectCount; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// //根据模板获取sql +// sql = FreemarkerParseFactory.parseTemplateContent(sql, data); +// NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); +// effectCount = namedParameterJdbcTemplate.update(sql, data); +// return effectCount; +// } +// +// public static Object findOne(final String dbKey, String sql, Object... param) { +// List> list; +// list = findList(dbKey, sql, param); +// if (oConvertUtils.listIsEmpty(list)) { +// log.error("Except one, but not find actually"); +// return null; +// } +// if (list.size() > 1) { +// log.error("Except one, but more than one actually"); +// } +// return list.get(0); +// } +// +// /** +// * 支持miniDao语法操作的查询 返回HashMap +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// public static Object findOneByHash(final String dbKey, String sql, HashMap data) { +// List> list; +// list = findListByHash(dbKey, sql, data); +// if (oConvertUtils.listIsEmpty(list)) { +// log.error("Except one, but not find actually"); +// } +// if (list.size() > 1) { +// log.error("Except one, but more than one actually"); +// } +// return list.get(0); +// } +// +// /** +// * 直接sql查询 根据clazz返回单个实例 +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句 +// * @param clazz 返回实例的Class +// * @param param +// * @return +// */ +// @SuppressWarnings("unchecked") +// public static Object findOne(final String dbKey, String sql, Class clazz, Object... param) { +// Map map = (Map) findOne(dbKey, sql, param); +// return ReflectHelper.setAll(clazz, map); +// } +// +// /** +// * 支持miniDao语法操作的查询 返回单个实例 +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param clazz 返回实例的Class +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// @SuppressWarnings("unchecked") +// public static Object findOneByHash(final String dbKey, String sql, Class clazz, HashMap data) { +// Map map = (Map) findOneByHash(dbKey, sql, data); +// return ReflectHelper.setAll(clazz, map); +// } +// +// public static List> findList(final String dbKey, String sql, Object... param) { +// List> list; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// +// if (ArrayUtils.isEmpty(param)) { +// list = jdbcTemplate.queryForList(sql); +// } else { +// list = jdbcTemplate.queryForList(sql, param); +// } +// return list; +// } +// +// /** +// * 查询数量 +// * @param dbKey +// * @param sql +// * @param param +// * @return +// */ +// public static Map queryCount(String dbKey, String sql, Map param){ +// NamedParameterJdbcTemplate npJdbcTemplate = getNamedParameterJdbcTemplate(dbKey); +// return npJdbcTemplate.queryForMap(sql, param); +// } +// +// /** +// * 查询列表数据 +// * @param dbKey +// * @param sql +// * @param param +// * @return +// */ +// public static List> findListByNamedParam(final String dbKey, String sql, Map param) { +// NamedParameterJdbcTemplate npJdbcTemplate = getNamedParameterJdbcTemplate(dbKey); +// List> list = npJdbcTemplate.queryForList(sql, param); +// return list; +// } +// +// /** +// * 支持miniDao语法操作的查询 +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// public static List> findListByHash(final String dbKey, String sql, HashMap data) { +// List> list; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// //根据模板获取sql +// sql = FreemarkerParseFactory.parseTemplateContent(sql, data); +// NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); +// list = namedParameterJdbcTemplate.queryForList(sql, data); +// return list; +// } +// +// /** +// * 此方法只能返回单列,不能返回实体类 +// * @param dbKey 数据源的key +// * @param sql sal +// * @param clazz 类 +// * @param param 参数 +// * @param +// * @return +// */ +// public static List findList(final String dbKey, String sql, Class clazz, Object... param) { +// List list; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// +// if (ArrayUtils.isEmpty(param)) { +// list = jdbcTemplate.queryForList(sql, clazz); +// } else { +// list = jdbcTemplate.queryForList(sql, clazz, param); +// } +// return list; +// } +// +// /** +// * 支持miniDao语法操作的查询 返回单列数据list +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param clazz 类型Long、String等 +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// public static List findListByHash(final String dbKey, String sql, Class clazz, HashMap data) { +// List list; +// JdbcTemplate jdbcTemplate = getJdbcTemplate(dbKey); +// //根据模板获取sql +// sql = FreemarkerParseFactory.parseTemplateContent(sql, data); +// NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource()); +// list = namedParameterJdbcTemplate.queryForList(sql, data, clazz); +// return list; +// } +// +// /** +// * 直接sql查询 返回实体类列表 +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持 minidao 语法逻辑 +// * @param clazz 返回实体类列表的class +// * @param param sql拼接注入中需要的数据 +// * @return +// */ +// public static List findListEntities(final String dbKey, String sql, Class clazz, Object... param) { +// List> queryList = findList(dbKey, sql, param); +// return ReflectHelper.transList2Entrys(queryList, clazz); +// } +// +// /** +// * 支持miniDao语法操作的查询 返回实体类列表 +// * +// * @param dbKey 数据源标识 +// * @param sql 执行sql语句,sql支持minidao语法逻辑 +// * @param clazz 返回实体类列表的class +// * @param data sql语法中需要判断的数据及sql拼接注入中需要的数据 +// * @return +// */ +// public static List findListEntitiesByHash(final String dbKey, String sql, Class clazz, HashMap data) { +// List> queryList = findListByHash(dbKey, sql, data); +// return ReflectHelper.transList2Entrys(queryList, clazz); +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/db/FreemarkerParseFactory.java b/digital-system/src/main/java/digital/system/jeecg/group/util/db/FreemarkerParseFactory.java new file mode 100644 index 0000000..0b8843d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/db/FreemarkerParseFactory.java @@ -0,0 +1,182 @@ +package digital.system.jeecg.group.util.db; + +import freemarker.cache.StringTemplateLoader; +import freemarker.core.ParseException; +import freemarker.template.Configuration; +import freemarker.template.Template; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.jeecgframework.codegenerate.generate.util.SimpleFormat; +import digital.base.constant.DataBaseConstant; +import digital.base.constant.SymbolConstant; + +import java.io.StringWriter; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * @author 赵俊夫 + * @version V1.0 + * @Title:FreemarkerHelper + * @description:Freemarker引擎协助类 + * @date Jul 5, 2013 2:58:29 PM + */ +@Slf4j +public class FreemarkerParseFactory { + + private static final String ENCODE = "utf-8"; + /** + * 参数格式化工具类 + */ + private static final String MINI_DAO_FORMAT = "DaoFormat"; + + /** + * 文件缓存 + */ + private static final Configuration TPL_CONFIG = new Configuration(); + /** + * SQL 缓存 + */ + private static final Configuration SQL_CONFIG = new Configuration(); + + private static StringTemplateLoader stringTemplateLoader = new StringTemplateLoader(); + + /**使用内嵌的(?ms)打开单行和多行模式*/ + private final static Pattern NOTES_PATTERN = Pattern + .compile("(?ms)/\\*.*?\\*/|^\\s*//.*?$"); + + static { + TPL_CONFIG.setClassForTemplateLoading( + new FreemarkerParseFactory().getClass(), "/"); + TPL_CONFIG.setNumberFormat("0.#####################"); + SQL_CONFIG.setTemplateLoader(stringTemplateLoader); + SQL_CONFIG.setNumberFormat("0.#####################"); + //classic_compatible设置,解决报空指针错误 + SQL_CONFIG.setClassicCompatible(true); + } + + /** + * 判断模板是否存在 + * + * @throws Exception + */ + public static boolean isExistTemplate(String tplName) throws Exception { + try { + Template mytpl = TPL_CONFIG.getTemplate(tplName, "UTF-8"); + if (mytpl == null) { + return false; + } + } catch (Exception e) { + //update-begin--Author:scott Date:20180320 for:解决问题 - 错误提示sql文件不存在,实际问题是sql freemarker用法错误----- + if (e instanceof ParseException) { + log.error(e.getMessage(), e.fillInStackTrace()); + throw new Exception(e); + } + log.debug("----isExistTemplate----" + e.toString()); + //update-end--Author:scott Date:20180320 for:解决问题 - 错误提示sql文件不存在,实际问题是sql freemarker用法错误------ + return false; + } + return true; + } + + /** + * 解析ftl模板 + * + * @param tplName 模板名 + * @param paras 参数 + * @return + */ + public static String parseTemplate(String tplName, Map paras) { + try { + log.debug(" minidao sql templdate : " + tplName); + StringWriter swriter = new StringWriter(); + Template mytpl = TPL_CONFIG.getTemplate(tplName, ENCODE); + if (paras.containsKey(MINI_DAO_FORMAT)) { + throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!"); + } + paras.put(MINI_DAO_FORMAT, new SimpleFormat()); + mytpl.process(paras, swriter); + String sql = getSqlText(swriter.toString()); + paras.remove(MINI_DAO_FORMAT); + return sql; + } catch (Exception e) { + log.error(e.getMessage(), e.fillInStackTrace()); + log.error("发送一次的模板key:{ " + tplName + " }"); + //System.err.println(e.getMessage()); + //System.err.println("模板名:{ "+ tplName +" }"); + throw new RuntimeException("解析SQL模板异常"); + } + } + + /** + * 解析ftl + * + * @param tplContent 模板内容 + * @param paras 参数 + * @return String 模板解析后内容 + */ + public static String parseTemplateContent(String tplContent, + Map paras) { + try { + String sqlUnderline="sql_"; + StringWriter swriter = new StringWriter(); + if (stringTemplateLoader.findTemplateSource(sqlUnderline + tplContent.hashCode()) == null) { + stringTemplateLoader.putTemplate(sqlUnderline + tplContent.hashCode(), tplContent); + } + Template mytpl = SQL_CONFIG.getTemplate(sqlUnderline + tplContent.hashCode(), ENCODE); + if (paras.containsKey(MINI_DAO_FORMAT)) { + throw new RuntimeException("DaoFormat 是 minidao 保留关键字,不允许使用 ,请更改参数定义!"); + } + paras.put(MINI_DAO_FORMAT, new SimpleFormat()); + mytpl.process(paras, swriter); + String sql = getSqlText(swriter.toString()); + paras.remove(MINI_DAO_FORMAT); + return sql; + } catch (Exception e) { + log.error(e.getMessage(), e.fillInStackTrace()); + log.error("发送一次的模板key:{ " + tplContent + " }"); + //System.err.println(e.getMessage()); + //System.err.println("模板内容:{ "+ tplContent +" }"); + throw new RuntimeException("解析SQL模板异常"); + } + } + + /** + * 除去无效字段,去掉注释 不然批量处理可能报错 去除无效的等于 + */ + private static String getSqlText(String sql) { + // 将注释替换成"" + sql = NOTES_PATTERN.matcher(sql).replaceAll(""); + sql = sql.replaceAll("\\n", " ").replaceAll("\\t", " ") + .replaceAll("\\s{1,}", " ").trim(); + // 去掉 最后是 where这样的问题 + //where空格 "where " + String whereSpace = DataBaseConstant.SQL_WHERE+" "; + //"where and" + String whereAnd = DataBaseConstant.SQL_WHERE+" and"; + //", where" + String commaWhere = SymbolConstant.COMMA+" "+DataBaseConstant.SQL_WHERE; + //", " + String commaSpace = SymbolConstant.COMMA + " "; + if (sql.endsWith(DataBaseConstant.SQL_WHERE) || sql.endsWith(whereSpace)) { + sql = sql.substring(0, sql.lastIndexOf("where")); + } + // 去掉where and 这样的问题 + int index = 0; + while ((index = StringUtils.indexOfIgnoreCase(sql, whereAnd, index)) != -1) { + sql = sql.substring(0, index + 5) + + sql.substring(index + 9, sql.length()); + } + // 去掉 , where 这样的问题 + index = 0; + while ((index = StringUtils.indexOfIgnoreCase(sql, commaWhere, index)) != -1) { + sql = sql.substring(0, index) + + sql.substring(index + 1, sql.length()); + } + // 去掉 最后是 ,这样的问题 + if (sql.endsWith(SymbolConstant.COMMA) || sql.endsWith(commaSpace)) { + sql = sql.substring(0, sql.lastIndexOf(",")); + } + return sql; + } +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/group/util/db/RoleIndexConfigEnum.java b/digital-system/src/main/java/digital/system/jeecg/group/util/db/RoleIndexConfigEnum.java new file mode 100644 index 0000000..1694abc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/group/util/db/RoleIndexConfigEnum.java @@ -0,0 +1,103 @@ +package digital.system.jeecg.group.util.db; + + +import digital.util.util.oConvertUtils; + +import java.util.List; + +/** + * 首页自定义 + * 通过角色编码与首页组件路径配置 + * 枚举的顺序有权限高低权重作用(也就是配置多个角色,在前面的角色首页,会优先生效) + * + * @author: smcp + */ +public enum RoleIndexConfigEnum { + + /** + * 首页自定义 admin + */ + ADMIN("admin", "dashboard/Analysis"), + //TEST("test", "dashboard/IndexChart"), + /** + * 首页自定义 hr + */ + HR("hr", "dashboard/IndexBdc"); + //DM("dm", "dashboard/IndexTask"), + + /** + * 角色编码 + */ + String roleCode; + /** + * 路由index + */ + String componentUrl; + + /** + * 构造器 + * + * @param roleCode 角色编码 + * @param componentUrl 首页组件路径(规则跟菜单配置一样) + */ + RoleIndexConfigEnum(String roleCode, String componentUrl) { + this.roleCode = roleCode; + this.componentUrl = componentUrl; + } + + /** + * 根据code找枚举 + * + * @param roleCode 角色编码 + * @return + */ + private static RoleIndexConfigEnum getEnumByCode(String roleCode) { + for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { + if (e.roleCode.equals(roleCode)) { + return e; + } + } + return null; + } + + /** + * 根据code找index + * + * @param roleCode 角色编码 + * @return + */ + private static String getIndexByCode(String roleCode) { + for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { + if (e.roleCode.equals(roleCode)) { + return e.componentUrl; + } + } + return null; + } + + public static String getIndexByRoles(List roles) { + String[] rolesArray = roles.toArray(new String[roles.size()]); + for (RoleIndexConfigEnum e : RoleIndexConfigEnum.values()) { + if (oConvertUtils.isIn(e.roleCode, rolesArray)) { + return e.componentUrl; + } + } + return null; + } + + public String getRoleCode() { + return roleCode; + } + + public void setRoleCode(String roleCode) { + this.roleCode = roleCode; + } + + public String getComponentUrl() { + return componentUrl; + } + + public void setComponentUrl(String componentUrl) { + this.componentUrl = componentUrl; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageController.java b/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageController.java new file mode 100644 index 0000000..8c326a2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageController.java @@ -0,0 +1,135 @@ +package digital.system.jeecg.message.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.message.service.ISysMessageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.controller.JeecgController; +import digital.system.jeecg.message.entity.SysMessage; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + +/** + * @Description: 消息 + * @author: smcp + * @date: 2019-04-09 + * @version: V1.0 + */ +@Slf4j +@RestController +@RequestMapping("/sys/message/sysMessage") +public class SysMessageController extends JeecgController { + @Autowired + private ISysMessageService sysMessageService; + + /** + * 分页列表查询 + * + * @param sysMessage + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @GetMapping(value = "/list") + public Result queryPageList(SysMessage sysMessage, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysMessage, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysMessageService.page(page, queryWrapper); + return Result.ok(pageList); + } + + /** + * 添加 + * + * @param sysMessage + * @return + */ + @PostMapping(value = "/add") + public Result add(@RequestBody SysMessage sysMessage) { + sysMessageService.save(sysMessage); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param sysMessage + * @return + */ + @PutMapping(value = "/edit") + public Result edit(@RequestBody SysMessage sysMessage) { + sysMessageService.updateById(sysMessage); + return Result.ok("修改成功!"); + + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + sysMessageService.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + + this.sysMessageService.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + SysMessage sysMessage = sysMessageService.getById(id); + return Result.ok(sysMessage); + } + + /** + * 导出excel + * + * @param request + */ + @GetMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysMessage sysMessage) { + return super.exportXls(request, sysMessage, SysMessage.class, "推送消息模板"); + } + + /** + * excel导入 + * + * @param request + * @param response + * @return + */ + @PostMapping(value = "/importExcel") + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SysMessage.class); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageTemplateController.java b/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageTemplateController.java new file mode 100644 index 0000000..22a3e55 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/controller/SysMessageTemplateController.java @@ -0,0 +1,160 @@ +//package digital.system.jeecg.message.controller; +// +//import com.alibaba.fastjson.JSON; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import digital.system.jeecg.group.query.QueryGenerator; +//import digital.system.jeecg.message.service.ISysMessageTemplateService; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import org.springframework.web.servlet.ModelAndView; +//import digital.base.vo.Result; +//import digital.system.jeecg.group.base.controller.JeecgController; +//import digital.system.jeecg.message.entity.MsgParams; +//import digital.system.jeecg.message.entity.SysMessageTemplate; +//import digital.system.jeecg.message.util.PushMsgUtil; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.util.Arrays; +//import java.util.Map; +// +///** +// * @Description: 消息模板 +// * @Author: zita +// * @Sate: 2019-04-09 +// * @Version: V1.0 +// */ +//@Slf4j +//@RestController +//@RequestMapping("/sys/message/sysMessageTemplate") +//public class SysMessageTemplateController extends JeecgController { +// @Autowired +// private ISysMessageTemplateService sysMessageTemplateService; +// @Autowired +// private PushMsgUtil pushMsgUtil; +// +// /** +// * 分页列表查询 +// * +// * @param sysMessageTemplate +// * @param pageNo +// * @param pageSize +// * @param req +// * @return +// */ +// @GetMapping(value = "/list") +// public Result queryPageList(SysMessageTemplate sysMessageTemplate, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysMessageTemplate, req.getParameterMap()); +// Page page = new Page(pageNo, pageSize); +// IPage pageList = sysMessageTemplateService.page(page, queryWrapper); +// return Result.ok(pageList); +// } +// +// /** +// * 添加 +// * +// * @param sysMessageTemplate +// * @return +// */ +// @PostMapping(value = "/add") +// public Result add(@RequestBody SysMessageTemplate sysMessageTemplate) { +// sysMessageTemplateService.save(sysMessageTemplate); +// return Result.ok("添加成功!"); +// } +// +// /** +// * 编辑 +// * +// * @param sysMessageTemplate +// * @return +// */ +// @PutMapping(value = "/edit") +// public Result edit(@RequestBody SysMessageTemplate sysMessageTemplate) { +// sysMessageTemplateService.updateById(sysMessageTemplate); +// return Result.ok("更新成功!"); +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @DeleteMapping(value = "/delete") +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// sysMessageTemplateService.removeById(id); +// return Result.ok("删除成功!"); +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @DeleteMapping(value = "/deleteBatch") +// public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { +// this.sysMessageTemplateService.removeByIds(Arrays.asList(ids.split(","))); +// return Result.ok("批量删除成功!"); +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// @GetMapping(value = "/queryById") +// public Result queryById(@RequestParam(name = "id", required = true) String id) { +// SysMessageTemplate sysMessageTemplate = sysMessageTemplateService.getById(id); +// return Result.ok(sysMessageTemplate); +// } +// +// /** +// * 导出excel +// * +// * @param request +// */ +// @GetMapping(value = "/exportXls") +// public ModelAndView exportXls(HttpServletRequest request, SysMessageTemplate sysMessageTemplate) { +// return super.exportXls(request, sysMessageTemplate, SysMessageTemplate.class, "推送消息模板"); +// } +// +// /** +// * excel导入 +// * +// * @param request +// * @param response +// * @return +// */ +// @PostMapping(value = "/importExcel") +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// return super.importExcel(request, response, SysMessageTemplate.class); +// } +// +// /** +// * 发送消息 +// */ +// @PostMapping(value = "/sendMsg") +// public Result sendMessage(@RequestBody MsgParams msgParams) { +// Result result = new Result(); +// Map map = null; +// try { +// map = (Map) JSON.parse(msgParams.getTestData()); +// } catch (Exception e) { +// result.error500("解析Json出错!"); +// return result; +// } +// boolean is_sendSuccess = pushMsgUtil.sendMessage(msgParams.getMsgType(), msgParams.getTemplateCode(), map, msgParams.getReceiver()); +// if (is_sendSuccess) { +// result.success("发送消息任务添加成功!"); +// } else { +// result.error500("发送消息任务添加失败!"); +// } +// return result; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/entity/MsgParams.java b/digital-system/src/main/java/digital/system/jeecg/message/entity/MsgParams.java new file mode 100644 index 0000000..0885cb3 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/entity/MsgParams.java @@ -0,0 +1,36 @@ +package digital.system.jeecg.message.entity; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 发送消息实体 + * + * @author: smcp + */ +@Data +public class MsgParams implements Serializable { + + private static final long serialVersionUID = 1L; + /** + * 消息类型 + */ + private String msgType; + + /** + * 消息接收方 + */ + private String receiver; + + /** + * 消息模板码 + */ + private String templateCode; + + /** + * 测试数据 + */ + private String testData; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessage.java b/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessage.java new file mode 100644 index 0000000..e7b325c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessage.java @@ -0,0 +1,79 @@ +package digital.system.jeecg.message.entity; + + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; +import digital.bean.jeecg.entity.JeecgEntity; + +/** + * @Description: 消息 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("sys_sms") +public class SysMessage extends JeecgEntity { + /** + * 推送内容 + */ + @Excel(name = "推送内容", width = 15) + private java.lang.String esContent; + /** + * 推送所需参数Json格式 + */ + @Excel(name = "推送所需参数Json格式", width = 15) + private java.lang.String esParam; + /** + * 接收人 + */ + @Excel(name = "接收人", width = 15) + private java.lang.String esReceiver; + /** + * 推送失败原因 + */ + @Excel(name = "推送失败原因", width = 15) + private java.lang.String esResult; + /** + * 发送次数 + */ + @Excel(name = "发送次数", width = 15) + private Integer esSendNum; + /** + * 推送状态 0未推送 1推送成功 2推送失败 + */ + @Excel(name = "推送状态 0未推送 1推送成功 2推送失败", width = 15) + @Dict(dicCode = "msgSendStatus") + private java.lang.String esSendStatus; + /** + * 推送时间 + */ + @Excel(name = "推送时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date esSendTime; + /** + * 消息标题 + */ + @Excel(name = "消息标题", width = 15) + private java.lang.String esTitle; + /** + * 推送方式:1短信 2邮件 3微信 + */ + @Excel(name = "推送方式:1短信 2邮件 3微信", width = 15) + @Dict(dicCode = "msgType") + private java.lang.String esType; + /** + * 备注 + */ + @Excel(name = "备注", width = 15) + private java.lang.String remark; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessageTemplate.java b/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessageTemplate.java new file mode 100644 index 0000000..ea66fb3 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/entity/SysMessageTemplate.java @@ -0,0 +1,47 @@ +package digital.system.jeecg.message.entity; + + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import digital.bean.jeecg.entity.JeecgEntity; + +/** + * @Description: 消息模板 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@TableName("sys_sms_template") +public class SysMessageTemplate extends JeecgEntity { + /** + * 模板CODE + */ + @Excel(name = "模板CODE", width = 15) + private java.lang.String templateCode; + /** + * 模板标题 + */ + @Excel(name = "模板标题", width = 30) + private java.lang.String templateName; + /** + * 模板内容 + */ + @Excel(name = "模板内容", width = 50) + private java.lang.String templateContent; + /** + * 模板测试json + */ + @Excel(name = "模板测试json", width = 15) + private java.lang.String templateTestJson; + /** + * 模板类型 + */ + @Excel(name = "模板类型", width = 15) + private java.lang.String templateType; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/ISendMsgHandle.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/ISendMsgHandle.java new file mode 100644 index 0000000..e1eab30 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/ISendMsgHandle.java @@ -0,0 +1,17 @@ +package digital.system.jeecg.message.handle; + +/** + * @Description: 发送信息接口 + * @author: smcp + */ +public interface ISendMsgHandle { + + /** + * 发送信息 + * + * @param es_receiver 发送人 + * @param es_title 标题 + * @param es_content 内容 + */ +// void SendMsg(String es_receiver, String es_title, String es_content); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgStatusEnum.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgStatusEnum.java new file mode 100644 index 0000000..fb34512 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgStatusEnum.java @@ -0,0 +1,27 @@ +package digital.system.jeecg.message.handle.enums; + +/** + * 推送状态枚举 + * + * @author: smcp + */ +public enum SendMsgStatusEnum { + + //推送状态 0未推送 1推送成功 2推送失败 + WAIT("0"), SUCCESS("1"), FAIL("2"); + + private String code; + + private SendMsgStatusEnum(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + + public void setStatusCode(String code) { + this.code = code; + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgTypeEnum.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgTypeEnum.java new file mode 100644 index 0000000..bf54e8c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/enums/SendMsgTypeEnum.java @@ -0,0 +1,66 @@ +package digital.system.jeecg.message.handle.enums; + + +import digital.util.util.oConvertUtils; + +/** + * 发送消息类型枚举 + * + * @author: smcp + */ +public enum SendMsgTypeEnum { + + /** + * 短信 + */ + SMS("1", "digital.system.modules.message.handle.impl.SmsSendMsgHandle"), + /** + * 邮件 + */ + EMAIL("2", "digital.system.modules.message.handle.impl.EmailSendMsgHandle"), + /** + * 微信 + */ + WX("3", "digital.system.modules.message.handle.impl.WxSendMsgHandle"), + /** + * 系统消息 + */ + SYSTEM_MESSAGE("4", "digital.system.modules.message.handle.impl.SystemSendMsgHandle"); + + private String type; + + private String implClass; + + private SendMsgTypeEnum(String type, String implClass) { + this.type = type; + this.implClass = implClass; + } + + public static SendMsgTypeEnum getByType(String type) { + if (oConvertUtils.isEmpty(type)) { + return null; + } + for (SendMsgTypeEnum val : values()) { + if (val.getType().equals(type)) { + return val; + } + } + return null; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getImplClass() { + return implClass; + } + + public void setImplClass(String implClass) { + this.implClass = implClass; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/EmailSendMsgHandle.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/EmailSendMsgHandle.java new file mode 100644 index 0000000..1b61388 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/EmailSendMsgHandle.java @@ -0,0 +1,44 @@ +//package digital.system.modules.message.handle.impl; +// +// +//import org.springframework.mail.javamail.JavaMailSender; +//import org.springframework.mail.javamail.MimeMessageHelper; +//import digital.system.modules.message.handle.ISendMsgHandle; +//import digital.util.util.SpringContextUtils; +//import digital.util.util.oConvertUtils; +///** +// * @Description: 邮箱发送信息 +// * @author: smcp +// */ +//public class EmailSendMsgHandle implements ISendMsgHandle { +// static String emailFrom; +// +// public static void setEmailFrom(String emailFrom) { +// EmailSendMsgHandle.emailFrom = emailFrom; +// } +// +// @Override +// public void SendMsg(String es_receiver, String es_title, String es_content) { +// JavaMailSender mailSender = (JavaMailSender) SpringContextUtils.getBean("mailSender"); +// MimeMessage message = mailSender.createMimeMessage(); +// MimeMessageHelper helper = null; +// //update-begin-author:taoyan date:20200811 for:配置类数据获取 +// if (oConvertUtils.isEmpty(emailFrom)) { +// StaticConfig staticConfig = SpringContextUtils.getBean(StaticConfig.class); +// setEmailFrom(staticConfig.getEmailFrom()); +// } +// //update-end-author:taoyan date:20200811 for:配置类数据获取 +// try { +// helper = new MimeMessageHelper(message, true); +// // 设置发送方邮箱地址 +// helper.setFrom(emailFrom); +// helper.setTo(es_receiver); +// helper.setSubject(es_title); +// helper.setText(es_content, true); +// mailSender.send(message); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SmsSendMsgHandle.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SmsSendMsgHandle.java new file mode 100644 index 0000000..34c0a49 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SmsSendMsgHandle.java @@ -0,0 +1,19 @@ +//package digital.system.modules.message.handle.impl; +// +//import lombok.extern.slf4j.Slf4j; +//import digital.system.modules.message.handle.ISendMsgHandle; +// +///** +// * @Description: 短信发送 +// * @author: smcp +// */ +//@Slf4j +//public class SmsSendMsgHandle implements ISendMsgHandle { +//// +//// @Override +//// public void SendMsg(String es_receiver, String es_title, String es_content) { +//// // TODO Auto-generated method stub +//// log.info("发短信"); +//// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SystemSendMsgHandle.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SystemSendMsgHandle.java new file mode 100644 index 0000000..15cf2fe --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/SystemSendMsgHandle.java @@ -0,0 +1,24 @@ +package digital.system.jeecg.message.handle.impl; + +import digital.system.jeecg.message.handle.ISendMsgHandle; + + +/** + * @Description: 发送系统消息 + * @Author: wangshuai + * @Date: 2022年3月22日 18:48:20 + */ +public class SystemSendMsgHandle implements ISendMsgHandle { + + public static final String FROM_USER = "system"; + +// @Override +// public void SendMsg(String es_receiver, String es_title, String es_content) { +// if (oConvertUtils.isEmpty(es_receiver)) { +// throw new JeecgBootException("被发送人不能为空"); +// } +// ISysBaseAPI sysBaseAPI = SpringContextUtils.getBean(ISysBaseAPI.class); +// MessageDTO messageDTO = new MessageDTO(FROM_USER, es_receiver, es_title, es_content); +// sysBaseAPI.sendSysAnnouncement(messageDTO); +// } +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/WxSendMsgHandle.java b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/WxSendMsgHandle.java new file mode 100644 index 0000000..ffe5861 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/handle/impl/WxSendMsgHandle.java @@ -0,0 +1,19 @@ +//package digital.system.modules.message.handle.impl; +// +//import lombok.extern.slf4j.Slf4j; +//import digital.system.modules.message.handle.ISendMsgHandle; +// +///** +// * @Description: 发微信消息模板 +// * @author: smcp +// */ +//@Slf4j +//public class WxSendMsgHandle implements ISendMsgHandle { +// +// @Override +// public void SendMsg(String es_receiver, String es_title, String es_content) { +// // TODO Auto-generated method stub +// log.info("发微信消息模板"); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageMapper.java b/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageMapper.java new file mode 100644 index 0000000..38bf5b2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.message.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.message.entity.SysMessage; + +/** + * @Description: 消息 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +public interface SysMessageMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageTemplateMapper.java b/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageTemplateMapper.java new file mode 100644 index 0000000..c5a46b7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/mapper/SysMessageTemplateMapper.java @@ -0,0 +1,25 @@ +package digital.system.jeecg.message.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Select; +import digital.system.jeecg.message.entity.SysMessageTemplate; + +import java.util.List; + +/** + * @Description: 消息模板 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +public interface SysMessageTemplateMapper extends BaseMapper { + + /** + * 通过模板CODE查询消息模板 + * + * @param code 模板CODE + * @return List + */ + @Select("SELECT * FROM SYS_SMS_TEMPLATE WHERE TEMPLATE_CODE = #{code}") + List selectByCode(String code); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/ChUserFileMapper.xml b/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/ChUserFileMapper.xml new file mode 100644 index 0000000..2ef5865 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/ChUserFileMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/SysMessageTemplateMapper.xml b/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/SysMessageTemplateMapper.xml new file mode 100644 index 0000000..35e8b1a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/mapper/xml/SysMessageTemplateMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageService.java b/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageService.java new file mode 100644 index 0000000..0605b36 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageService.java @@ -0,0 +1,15 @@ +package digital.system.jeecg.message.service; + + +import digital.system.jeecg.group.base.service.JeecgService; +import digital.system.jeecg.message.entity.SysMessage; + +/** + * @Description: 消息 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +public interface ISysMessageService extends JeecgService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageTemplateService.java b/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageTemplateService.java new file mode 100644 index 0000000..e58c4b7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/service/ISysMessageTemplateService.java @@ -0,0 +1,23 @@ +package digital.system.jeecg.message.service; + +import digital.system.jeecg.group.base.service.JeecgService; +import digital.system.jeecg.message.entity.SysMessageTemplate; + +import java.util.List; + +/** + * @Description: 消息模板 + * @Author: zita + * @Date: 2019-04-09 + * @Version: V1.0 + */ +public interface ISysMessageTemplateService extends JeecgService { + + /** + * 通过模板CODE查询消息模板 + * + * @param code 模板CODE + * @return + */ + List selectByCode(String code); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageServiceImpl.java new file mode 100644 index 0000000..e8e7f97 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageServiceImpl.java @@ -0,0 +1,19 @@ +package digital.system.jeecg.message.service.impl; + + +import org.springframework.stereotype.Service; +import digital.system.jeecg.group.base.service.impl.JeecgServiceImpl; +import digital.system.jeecg.message.entity.SysMessage; +import digital.system.jeecg.message.mapper.SysMessageMapper; +import digital.system.jeecg.message.service.ISysMessageService; + +/** + * @Description: 消息 + * @Author: digital + * @Date: 2019-04-09 + * @Version: V1.0 + */ +@Service +public class SysMessageServiceImpl extends JeecgServiceImpl implements ISysMessageService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageTemplateServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageTemplateServiceImpl.java new file mode 100644 index 0000000..6dff793 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/service/impl/SysMessageTemplateServiceImpl.java @@ -0,0 +1,30 @@ +package digital.system.jeecg.message.service.impl; + + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import digital.system.jeecg.group.base.service.impl.JeecgServiceImpl; +import digital.system.jeecg.message.entity.SysMessageTemplate; +import digital.system.jeecg.message.mapper.SysMessageTemplateMapper; +import digital.system.jeecg.message.service.ISysMessageTemplateService; + +import java.util.List; + +/** + * @Description: 消息模板 + * @Author: digital + * @Date: 2019-04-09 + * @Version: V1.0 + */ +@Service +public class SysMessageTemplateServiceImpl extends JeecgServiceImpl implements ISysMessageTemplateService { + + @Autowired + private SysMessageTemplateMapper sysMessageTemplateMapper; + + + @Override + public List selectByCode(String code) { + return sysMessageTemplateMapper.selectByCode(code); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/util/PushMsgUtil.java b/digital-system/src/main/java/digital/system/jeecg/message/util/PushMsgUtil.java new file mode 100644 index 0000000..052e2c8 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/util/PushMsgUtil.java @@ -0,0 +1,79 @@ +//package digital.system.jeecg.message.util; +// +//import com.alibaba.fastjson.JSONObject; +//import digital.system.jeecg.message.entity.SysMessage; +//import digital.system.jeecg.message.entity.SysMessageTemplate; +//import digital.system.jeecg.message.handle.enums.SendMsgStatusEnum; +//import digital.system.jeecg.message.service.ISysMessageService; +//import digital.system.jeecg.message.service.ISysMessageTemplateService; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Component; +// +//import java.io.IOException; +//import java.io.StringWriter; +//import java.util.Date; +//import java.util.List; +//import java.util.Map; +// +///** +// * 消息生成工具 +// * +// * @author: smcp +// */ +// +//@Component +//public class PushMsgUtil { +// +// @Autowired +// private ISysMessageService sysMessageService; +// +// @Autowired +// private ISysMessageTemplateService sysMessageTemplateService; +// +// @Autowired +// private Configuration freemarkerConfig; +// +// /** +// * @param msgType 消息类型 1短信 2邮件 3微信 +// * @param templateCode 消息模板码 +// * @param map 消息参数 +// * @param sentTo 接收消息方 +// */ +// public boolean sendMessage(String msgType, String templateCode, Map map, String sentTo) { +// List sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode); +// SysMessage sysMessage = new SysMessage(); +// if (sysSmsTemplates.size() > 0) { +// SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0); +// sysMessage.setEsType(msgType); +// sysMessage.setEsReceiver(sentTo); +// //模板标题 +// String title = sysSmsTemplate.getTemplateName(); +// //模板内容 +// String content = sysSmsTemplate.getTemplateContent(); +// StringWriter stringWriter = new StringWriter(); +// Template template = null; +// try { +// template = new Template("SysMessageTemplate", content, freemarkerConfig); +// template.process(map, stringWriter); +// } catch (IOException e) { +// e.printStackTrace(); +// return false; +// } catch (TemplateException e) { +// e.printStackTrace(); +// return false; +// } +// content = stringWriter.toString(); +// sysMessage.setEsTitle(title); +// sysMessage.setEsContent(content); +// sysMessage.setEsParam(JSONObject.toJSONString(map)); +// sysMessage.setEsSendTime(new Date()); +// sysMessage.setEsSendStatus(SendMsgStatusEnum.WAIT.getCode()); +// sysMessage.setEsSendNum(0); +// if (sysMessageService.save(sysMessage)) { +// return true; +// } +// } +// return false; +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/message/websocket/SocketHandler.java b/digital-system/src/main/java/digital/system/jeecg/message/websocket/SocketHandler.java new file mode 100644 index 0000000..a5abdf6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/websocket/SocketHandler.java @@ -0,0 +1,38 @@ +package digital.system.jeecg.message.websocket; + +import cn.hutool.core.util.ObjectUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import digital.base.constant.CommonSendStatus; +import digital.bean.jeecg.BaseMap; +import digital.system.jeecg.group.redis.listener.JeecgRedisListener; + +/** + * 监听消息(采用redis发布订阅方式发送消息) + * + * @author: smcp + */ +@Slf4j +@Component +public class SocketHandler implements JeecgRedisListener { + + @Autowired + private WebSocket webSocket; + + @Override + public void onMessage(BaseMap map) { + log.info("【SocketHandler消息】Redis Listerer:" + map.toString()); + + String userId = map.get("userId"); + String message = map.get("message"); + if (ObjectUtil.isNotEmpty(userId)) { + webSocket.pushMessage(userId, message); + //app端消息推送 + webSocket.pushMessage(userId + CommonSendStatus.APP_SESSION_SUFFIX, message); + } else { + webSocket.pushMessage(message); + } + + } +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/websocket/TestSocketController.java b/digital-system/src/main/java/digital/system/jeecg/message/websocket/TestSocketController.java new file mode 100644 index 0000000..417cb5a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/websocket/TestSocketController.java @@ -0,0 +1,52 @@ +package digital.system.jeecg.message.websocket; + + +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import digital.base.constant.WebsocketConst; +import digital.base.vo.Result; + +/** + * @Description: TestSocketController + * @author: smcp + */ +@RestController +@RequestMapping("/sys/socketTest") +public class TestSocketController { + + @Autowired + private WebSocket webSocket; + + @PostMapping("/sendAll") + public Result sendAll(@RequestBody JSONObject jsonObject) { + Result result = new Result(); + String message = jsonObject.getString("message"); + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC); + obj.put(WebsocketConst.MSG_ID, "M0001"); + obj.put(WebsocketConst.MSG_TXT, message); + webSocket.sendMessage(obj.toJSONString()); + result.setResult("群发!"); + return result; + } + + @PostMapping("/sendUser") + public Result sendUser(@RequestBody JSONObject jsonObject) { + Result result = new Result(); + String userId = jsonObject.getString("userId"); + String message = jsonObject.getString("message"); + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); + obj.put(WebsocketConst.MSG_USER_ID, userId); + obj.put(WebsocketConst.MSG_ID, "M0001"); + obj.put(WebsocketConst.MSG_TXT, message); + webSocket.sendMessage(userId, obj.toJSONString()); + result.setResult("单发"); + return result; + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/message/websocket/WebSocket.java b/digital-system/src/main/java/digital/system/jeecg/message/websocket/WebSocket.java new file mode 100644 index 0000000..163784c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/message/websocket/WebSocket.java @@ -0,0 +1,158 @@ +package digital.system.jeecg.message.websocket; + +import com.alibaba.fastjson.JSONObject; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; +import digital.base.constant.WebsocketConst; +import digital.bean.jeecg.BaseMap; +import digital.system.jeecg.group.redis.client.JeecgRedisClient; +import javax.annotation.Resource; +import javax.websocket.OnClose; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * @Author scott + * @Date 2019/11/29 9:41 + * @Description: 此注解相当于设置访问URL + */ +@Component +@Slf4j +@ServerEndpoint("/websocket/{userId}") +public class WebSocket { + + private static final String REDIS_TOPIC_NAME = "socketHandler"; + /** + * 缓存 webSocket连接到单机服务class中(整体方案支持集群) + */ + private static CopyOnWriteArraySet webSockets = new CopyOnWriteArraySet<>(); + /** + * 线程安全Map + */ + private static ConcurrentHashMap sessionPool = new ConcurrentHashMap<>(); + private Session session; + /** + * 用户ID + */ + private String userId; + @Resource + private JeecgRedisClient jeecgRedisClient; + + @OnOpen + public void onOpen(Session session, @PathParam(value = "userId") String userId) { + try { + //TODO 通过header中获取token,进行check + this.session = session; + this.userId = userId; + webSockets.add(this); + sessionPool.put(userId, session); + log.info("【websocket消息】有新的连接,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + @OnClose + public void onClose() { + try { + webSockets.remove(this); + sessionPool.remove(this.userId); + log.info("【websocket消息】连接断开,总数为:" + webSockets.size()); + } catch (Exception e) { + } + } + + + /** + * 服务端推送消息 + * + * @param userId + * @param message + */ + public void pushMessage(String userId, String message) { + Session session = sessionPool.get(userId); + if (session != null && session.isOpen()) { + try { + //update-begin-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/smcp/issues/I4C0MU + synchronized (session) { + log.info("【websocket消息】 单点消息:" + message); + session.getBasicRemote().sendText(message); + } + //update-end-author:taoyan date:20211012 for: websocket报错 https://gitee.com/jeecg/smcp/issues/I4C0MU + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 服务器端推送消息 + */ + public void pushMessage(String message) { + try { + webSockets.forEach(ws -> ws.session.getAsyncRemote().sendText(message)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + + @OnMessage + public void onMessage(String message) { + //todo 现在有个定时任务刷,应该去掉 + log.debug("【websocket消息】收到客户端消息:" + message); + JSONObject obj = new JSONObject(); + //业务类型 + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK); + //消息内容 + obj.put(WebsocketConst.MSG_TXT, "心跳响应"); + //update-begin-author:taoyan date:20220308 for: 消息通知长连接启动心跳机制,后端代码小bug #3473 + for (WebSocket webSocket : webSockets) { + webSocket.pushMessage(obj.toJSONString()); + } + //update-end-author:taoyan date:20220308 for: 消息通知长连接启动心跳机制,后端代码小bug #3473 + } + + /** + * 后台发送消息到redis + * + * @param message + */ + public void sendMessage(String message) { + log.info("【websocket消息】广播消息:" + message); + BaseMap baseMap = new BaseMap(); + baseMap.put("userId", ""); + baseMap.put("message", message); + jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap); + } + + /** + * 此为单点消息 + * + * @param userId + * @param message + */ + public void sendMessage(String userId, String message) { + BaseMap baseMap = new BaseMap(); + baseMap.put("userId", userId); + baseMap.put("message", message); + jeecgRedisClient.sendMessage(REDIS_TOPIC_NAME, baseMap); + } + + /** + * 此为单点消息(多人) + * + * @param userIds + * @param message + */ + public void sendMessage(String[] userIds, String message) { + for (String userId : userIds) { + sendMessage(userId, message); + } + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/controller/ActuatorRedisController.java b/digital-system/src/main/java/digital/system/jeecg/monitor/controller/ActuatorRedisController.java new file mode 100644 index 0000000..6b57c83 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/controller/ActuatorRedisController.java @@ -0,0 +1,129 @@ +package digital.system.jeecg.monitor.controller; + +import com.alibaba.fastjson.JSONArray; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import digital.base.vo.Result; +import digital.system.jeecg.monitor.domain.RedisInfo; +import digital.system.jeecg.monitor.service.RedisService; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.swing.filechooser.FileSystemView; +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @Description: ActuatorRedisController + * @author: smcp + */ +@Slf4j +@RestController +@RequestMapping("/sys/actuator/redis") +public class ActuatorRedisController { + + @Autowired + private RedisService redisService; + + /** + * Redis详细信息 + * + * @return + * @throws Exception + */ + @GetMapping("/info") + public Result getRedisInfo() throws Exception { + List infoList = this.redisService.getRedisInfo(); + log.info(infoList.toString()); + return Result.ok(infoList); + } + + @GetMapping("/keysSize") + public Map getKeysSize() throws Exception { + return redisService.getKeysSize(); + } + + /** + * 获取redis key数量 for 报表 + * + * @return + * @throws Exception + */ + @GetMapping("/keysSizeForReport") + public Map getKeysSizeReport() throws Exception { + return redisService.getMapForReport("1"); + } + + /** + * 获取redis 内存 for 报表 + * + * @return + * @throws Exception + */ + @GetMapping("/memoryForReport") + public Map memoryForReport() throws Exception { + return redisService.getMapForReport("2"); + } + + /** + * 获取redis 全部信息 for 报表 + * + * @return + * @throws Exception + */ + @GetMapping("/infoForReport") + public Map infoForReport() throws Exception { + return redisService.getMapForReport("3"); + } + + @GetMapping("/memoryInfo") + public Map getMemoryInfo() throws Exception { + return redisService.getMemoryInfo(); + } + + //update-begin--Author:zhangweijian Date:20190425 for:获取磁盘信息 + + /** + * @param request + * @param response + * @return + * @功能:获取磁盘信息 + */ + @GetMapping("/queryDiskInfo") + public Result>> queryDiskInfo(HttpServletRequest request, HttpServletResponse response) { + Result>> res = new Result<>(); + try { + // 当前文件系统类 + FileSystemView fsv = FileSystemView.getFileSystemView(); + // 列出所有windows 磁盘 + File[] fs = File.listRoots(); + log.info("查询磁盘信息:" + fs.length + "个"); + List> list = new ArrayList<>(); + + for (int i = 0; i < fs.length; i++) { + if (fs[i].getTotalSpace() == 0) { + continue; + } + Map map = new HashMap(5); + map.put("name", fsv.getSystemDisplayName(fs[i])); + map.put("max", fs[i].getTotalSpace()); + map.put("rest", fs[i].getFreeSpace()); + map.put("restPPT", (fs[i].getTotalSpace() - fs[i].getFreeSpace()) * 100 / fs[i].getTotalSpace()); + list.add(map); + log.info(map.toString()); + } + res.setResult(list); + res.success("查询成功"); + } catch (Exception e) { + res.error500("查询失败" + e.getMessage()); + } + return res; + } + //update-end--Author:zhangweijian Date:20190425 for:获取磁盘信息 +} diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/domain/RedisInfo.java b/digital-system/src/main/java/digital/system/jeecg/monitor/domain/RedisInfo.java new file mode 100644 index 0000000..b27a365 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/domain/RedisInfo.java @@ -0,0 +1,141 @@ +package digital.system.jeecg.monitor.domain; + +import java.util.HashMap; +import java.util.Map; + +/** + * @Description: redis信息 + * @author: smcp + */ +public class RedisInfo { + + private static Map map = new HashMap(5); + + static { + map.put("redis_version", "Redis 服务器版本"); + map.put("redis_git_sha1", "Git SHA1"); + map.put("redis_git_dirty", "Git dirty flag"); + map.put("os", "Redis 服务器的宿主操作系统"); + map.put("arch_bits", " 架构(32 或 64 位)"); + map.put("multiplexing_api", "Redis 所使用的事件处理机制"); + map.put("gcc_version", "编译 Redis 时所使用的 GCC 版本"); + map.put("process_id", "服务器进程的 PID"); + map.put("run_id", "Redis 服务器的随机标识符(用于 Sentinel 和集群)"); + map.put("tcp_port", "TCP/IP 监听端口"); + map.put("uptime_in_seconds", "自 Redis 服务器启动以来,经过的秒数"); + map.put("uptime_in_days", "自 Redis 服务器启动以来,经过的天数"); + map.put("lru_clock", " 以分钟为单位进行自增的时钟,用于 LRU 管理"); + map.put("connected_clients", "已连接客户端的数量(不包括通过从属服务器连接的客户端)"); + map.put("client_longest_output_list", "当前连接的客户端当中,最长的输出列表"); + map.put("client_longest_input_buf", "当前连接的客户端当中,最大输入缓存"); + map.put("blocked_clients", "正在等待阻塞命令(BLPOP、BRPOP、BRPOPLPUSH)的客户端的数量"); + map.put("used_memory", "由 Redis 分配器分配的内存总量,以字节(byte)为单位"); + map.put("used_memory_human", "以人类可读的格式返回 Redis 分配的内存总量"); + map.put("used_memory_rss", "从操作系统的角度,返回 Redis 已分配的内存总量(俗称常驻集大小)。这个值和 top 、 ps 等命令的输出一致"); + map.put("used_memory_peak", " Redis 的内存消耗峰值(以字节为单位)"); + map.put("used_memory_peak_human", "以人类可读的格式返回 Redis 的内存消耗峰值"); + map.put("used_memory_lua", "Lua 引擎所使用的内存大小(以字节为单位)"); + map.put("mem_fragmentation_ratio", "sed_memory_rss 和 used_memory 之间的比率"); + map.put("mem_allocator", "在编译时指定的, Redis 所使用的内存分配器。可以是 libc 、 jemalloc 或者 tcmalloc"); + + map.put("redis_build_id", "redis_build_id"); + map.put("redis_mode", "运行模式,单机(standalone)或者集群(cluster)"); + map.put("atomicvar_api", "atomicvar_api"); + map.put("hz", "redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,程序规定serverCron每秒运行10次。"); + map.put("executable", "server脚本目录"); + map.put("config_file", "配置文件目录"); + map.put("client_biggest_input_buf", "当前连接的客户端当中,最大输入缓存,用client list命令观察qbuf和qbuf-free两个字段最大值"); + map.put("used_memory_rss_human", "以人类可读的方式返回 Redis 已分配的内存总量"); + map.put("used_memory_peak_perc", "内存使用率峰值"); + map.put("total_system_memory", "系统总内存"); + map.put("total_system_memory_human", "以人类可读的方式返回系统总内存"); + map.put("used_memory_lua_human", "以人类可读的方式返回Lua 引擎所使用的内存大小"); + map.put("maxmemory", "最大内存限制,0表示无限制"); + map.put("maxmemory_human", "以人类可读的方式返回最大限制内存"); + map.put("maxmemory_policy", "超过内存限制后的处理策略"); + map.put("loading", "服务器是否正在载入持久化文件"); + map.put("rdb_changes_since_last_save", "离最近一次成功生成rdb文件,写入命令的个数,即有多少个写入命令没有持久化"); + map.put("rdb_bgsave_in_progress", "服务器是否正在创建rdb文件"); + map.put("rdb_last_save_time", "离最近一次成功创建rdb文件的时间戳。当前时间戳 - rdb_last_save_time=多少秒未成功生成rdb文件"); + map.put("rdb_last_bgsave_status", "最近一次rdb持久化是否成功"); + map.put("rdb_last_bgsave_time_sec", "最近一次成功生成rdb文件耗时秒数"); + map.put("rdb_current_bgsave_time_sec", "如果服务器正在创建rdb文件,那么这个域记录的就是当前的创建操作已经耗费的秒数"); + map.put("aof_enabled", "是否开启了aof"); + map.put("aof_rewrite_in_progress", "标识aof的rewrite操作是否在进行中"); + map.put("aof_rewrite_scheduled", "rewrite任务计划,当客户端发送bgrewriteaof指令,如果当前rewrite子进程正在执行,那么将客户端请求的bgrewriteaof变为计划任务,待aof子进程结束后执行rewrite "); + + map.put("aof_last_rewrite_time_sec", "最近一次aof rewrite耗费的时长"); + map.put("aof_current_rewrite_time_sec", "如果rewrite操作正在进行,则记录所使用的时间,单位秒"); + map.put("aof_last_bgrewrite_status", "上次bgrewrite aof操作的状态"); + map.put("aof_last_write_status", "上次aof写入状态"); + + map.put("total_commands_processed", "redis处理的命令数"); + map.put("total_connections_received", "新创建连接个数,如果新创建连接过多,过度地创建和销毁连接对性能有影响,说明短连接严重或连接池使用有问题,需调研代码的连接设置"); + map.put("instantaneous_ops_per_sec", "redis当前的qps,redis内部较实时的每秒执行的命令数"); + map.put("total_net_input_bytes", "redis网络入口流量字节数"); + map.put("total_net_output_bytes", "redis网络出口流量字节数"); + + map.put("instantaneous_input_kbps", "redis网络入口kps"); + map.put("instantaneous_output_kbps", "redis网络出口kps"); + map.put("rejected_connections", "拒绝的连接个数,redis连接个数达到maxclients限制,拒绝新连接的个数"); + map.put("sync_full", "主从完全同步成功次数"); + + map.put("sync_partial_ok", "主从部分同步成功次数"); + map.put("sync_partial_err", "主从部分同步失败次数"); + map.put("expired_keys", "运行以来过期的key的数量"); + map.put("evicted_keys", "运行以来剔除(超过了maxmemory后)的key的数量"); + map.put("keyspace_hits", "命中次数"); + map.put("keyspace_misses", "没命中次数"); + map.put("pubsub_channels", "当前使用中的频道数量"); + map.put("pubsub_patterns", "当前使用的模式的数量"); + map.put("latest_fork_usec", "最近一次fork操作阻塞redis进程的耗时数,单位微秒"); + map.put("role", "实例的角色,是master or slave"); + map.put("connected_slaves", "连接的slave实例个数"); + map.put("master_repl_offset", "主从同步偏移量,此值如果和上面的offset相同说明主从一致没延迟"); + map.put("repl_backlog_active", "复制积压缓冲区是否开启"); + map.put("repl_backlog_size", "复制积压缓冲大小"); + map.put("repl_backlog_first_byte_offset", "复制缓冲区里偏移量的大小"); + map.put("repl_backlog_histlen", "此值等于 master_repl_offset - repl_backlog_first_byte_offset,该值不会超过repl_backlog_size的大小"); + map.put("used_cpu_sys", "将所有redis主进程在核心态所占用的CPU时求和累计起来"); + map.put("used_cpu_user", "将所有redis主进程在用户态所占用的CPU时求和累计起来"); + map.put("used_cpu_sys_children", "将后台进程在核心态所占用的CPU时求和累计起来"); + map.put("used_cpu_user_children", "将后台进程在用户态所占用的CPU时求和累计起来"); + map.put("cluster_enabled", "实例是否启用集群模式"); + map.put("db0", "db0的key的数量,以及带有生存期的key的数,平均存活时间"); + + } + + private String key; + private String value; + private String description; + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + this.description = map.get(this.key); + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "RedisInfo{" + "key='" + key + '\'' + ", value='" + value + '\'' + ", desctiption='" + description + '\'' + '}'; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/exception/RedisConnectException.java b/digital-system/src/main/java/digital/system/jeecg/monitor/exception/RedisConnectException.java new file mode 100644 index 0000000..42ecaad --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/exception/RedisConnectException.java @@ -0,0 +1,15 @@ +package digital.system.jeecg.monitor.exception; + +/** + * Redis 连接异常 + * + * @author: smcp + */ +public class RedisConnectException extends Exception { + + private static final long serialVersionUID = 1639374111871115063L; + + public RedisConnectException(String message) { + super(message); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/service/RedisService.java b/digital-system/src/main/java/digital/system/jeecg/monitor/service/RedisService.java new file mode 100644 index 0000000..2c575c3 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/service/RedisService.java @@ -0,0 +1,48 @@ +package digital.system.jeecg.monitor.service; + +import com.alibaba.fastjson.JSONArray; +import digital.system.jeecg.monitor.domain.RedisInfo; +import digital.system.jeecg.monitor.exception.RedisConnectException; + +import java.util.List; +import java.util.Map; + +/** + * @Description: redis信息service接口 + * @author: smcp + */ +public interface RedisService { + + /** + * 获取 redis 的详细信息 + * + * @return List + * @throws RedisConnectException + */ + List getRedisInfo() throws RedisConnectException; + + /** + * 获取 redis key 数量 + * + * @return Map + * @throws RedisConnectException + */ + Map getKeysSize() throws RedisConnectException; + + /** + * 获取 redis 内存信息 + * + * @return Map + * @throws RedisConnectException + */ + Map getMemoryInfo() throws RedisConnectException; + + /** + * 获取 报表需要个redis信息 + * + * @param type + * @return Map + * @throws RedisConnectException + */ + Map getMapForReport(String type) throws RedisConnectException; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/MailHealthIndicator.java b/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/MailHealthIndicator.java new file mode 100644 index 0000000..ae6c8c9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/MailHealthIndicator.java @@ -0,0 +1,31 @@ +//package digital.system.jeecg.monitor.service.impl; +// +//import org.springframework.boot.actuate.health.Health; +//import org.springframework.boot.actuate.health.HealthIndicator; +//import org.springframework.stereotype.Component; +// +///** +// * 功能说明:自定义邮件检测 +// * +// * @author: 李波 +// * @email: 503378406@qq.com +// * @date: 2019-06-29 +// */ +//@Component +//public class MailHealthIndicator implements HealthIndicator { +// +// +// @Override +// public Health health() { +// int errorCode = check(); +// if (errorCode != 0) { +// return Health.down().withDetail("Error Code", errorCode).build(); +// } +// return Health.up().build(); +// } +// +// int check() { +// //可以实现自定义的数据库检测逻辑 +// return 0; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/RedisServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/RedisServiceImpl.java new file mode 100644 index 0000000..2f2efa0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/monitor/service/impl/RedisServiceImpl.java @@ -0,0 +1,117 @@ +package digital.system.jeecg.monitor.service.impl; + +import cn.hutool.core.date.DateUtil; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cglib.beans.BeanMap; +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.stereotype.Service; +import digital.system.jeecg.monitor.domain.RedisInfo; +import digital.system.jeecg.monitor.exception.RedisConnectException; +import digital.system.jeecg.monitor.service.RedisService; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.*; + +/** + * Redis 监控信息获取 + * + * @Author MrBird + */ +@Service("redisService") +@Slf4j +public class RedisServiceImpl implements RedisService { + + @Resource + private RedisConnectionFactory redisConnectionFactory; + + /** + * Redis详细信息 + */ + @Override + public List getRedisInfo() throws RedisConnectException { + Properties info = redisConnectionFactory.getConnection().info(); + List infoList = new ArrayList<>(); + RedisInfo redisInfo = null; + for (Map.Entry entry : info.entrySet()) { + redisInfo = new RedisInfo(); + redisInfo.setKey(oConvertUtils.getString(entry.getKey())); + redisInfo.setValue(oConvertUtils.getString(entry.getValue())); + infoList.add(redisInfo); + } + return infoList; + } + + @Override + public Map getKeysSize() throws RedisConnectException { + Long dbSize = redisConnectionFactory.getConnection().dbSize(); + Map map = new HashMap(5); + map.put("create_time", System.currentTimeMillis()); + map.put("dbSize", dbSize); + + log.debug("--getKeysSize--: " + map.toString()); + return map; + } + + @Override + public Map getMemoryInfo() throws RedisConnectException { + Map map = null; + Properties info = redisConnectionFactory.getConnection().info(); + for (Map.Entry entry : info.entrySet()) { + String key = oConvertUtils.getString(entry.getKey()); + if ("used_memory".equals(key)) { + map = new HashMap(5); + map.put("used_memory", entry.getValue()); + map.put("create_time", System.currentTimeMillis()); + } + } + log.debug("--getMemoryInfo--: " + map.toString()); + return map; + } + + /** + * 查询redis信息for报表 + * + * @param type 1redis key数量 2 占用内存 3redis信息 + * @return + * @throws RedisConnectException + */ + @Override + public Map getMapForReport(String type) throws RedisConnectException { + Map mapJson = new HashMap(5); + JSONArray json = new JSONArray(); + if ("3".equals(type)) { + List redisInfo = getRedisInfo(); + for (RedisInfo info : redisInfo) { + Map map = Maps.newHashMap(); + BeanMap beanMap = BeanMap.create(info); + for (Object key : beanMap.keySet()) { + map.put(key + "", beanMap.get(key)); + } + json.add(map); + } + mapJson.put("data", json); + return mapJson; + } + for (int i = 0; i < 5; i++) { + JSONObject jo = new JSONObject(); + Map map; + if ("1".equals(type)) { + map = getKeysSize(); + jo.put("value", map.get("dbSize")); + } else { + map = getMemoryInfo(); + Integer used_memory = Integer.valueOf(map.get("used_memory").toString()); + jo.put("value", used_memory / 1000); + } + String create_time = DateUtil.formatTime(DateUtil.date((Long) map.get("create_time") - (4 - i) * 1000)); + jo.put("name", create_time); + json.add(jo); + } + mapJson.put("data", json); + return mapJson; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/oss/controller/OSSFileController.java b/digital-system/src/main/java/digital/system/jeecg/oss/controller/OSSFileController.java new file mode 100644 index 0000000..7b37102 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/oss/controller/OSSFileController.java @@ -0,0 +1,95 @@ +package digital.system.jeecg.oss.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.oss.entity.OSSFile; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import digital.base.vo.Result; +import digital.system.jeecg.oss.service.IOSSFileService; + +import javax.servlet.http.HttpServletRequest; + +@Slf4j +@Controller +@RequestMapping("/oss/file") +@Api(tags = "通用上传接口") +public class OSSFileController { + + @Autowired + private IOSSFileService ossFileService; + + @ResponseBody + @GetMapping("/list") + public Result> queryPageList(OSSFile file, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + Result> result = new Result<>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(file, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = ossFileService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + @ResponseBody + @PostMapping("/upload") + //@RequiresRoles({"admin"}) + public Result upload(@RequestParam("file") MultipartFile multipartFile) { + Result result = new Result(); + try { + ossFileService.upload(multipartFile); + result.success("上传成功!"); + } + catch (Exception ex) { + log.info(ex.getMessage(), ex); + result.error500("上传失败"); + } + return result; + } + + @ResponseBody + @DeleteMapping("/delete") + public Result delete(@RequestParam(name = "id") String id) { + Result result = new Result(); + OSSFile file = ossFileService.getById(id); + if (file == null) { + result.error500("未找到对应实体"); + } + else { + boolean ok = ossFileService.delete(file); + if (ok) { + result.success("删除成功!"); + } + } + return result; + } + + /** + * 通过id查询. + */ + @ApiOperation(value = "通过id查询") + @ResponseBody + @GetMapping("/queryById") + public Result queryById(@RequestParam(name = "id") String id) { + Result result = new Result<>(); + OSSFile file = ossFileService.getById(id); + if (file == null) { + result.error500("未找到对应实体"); + } + else { + result.setResult(file); + result.setSuccess(true); + } + return result; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/oss/entity/OSSFile.java b/digital-system/src/main/java/digital/system/jeecg/oss/entity/OSSFile.java new file mode 100644 index 0000000..2e70fa7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/oss/entity/OSSFile.java @@ -0,0 +1,24 @@ +package digital.system.jeecg.oss.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import digital.bean.jeecg.entity.JeecgEntity; + +@Data +@TableName("oss_file") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class OSSFile extends JeecgEntity { + + private static final long serialVersionUID = 1L; + + @Excel(name = "文件名称") + private String fileName; + + @Excel(name = "文件地址") + private String url; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/oss/mapper/OSSFileMapper.java b/digital-system/src/main/java/digital/system/jeecg/oss/mapper/OSSFileMapper.java new file mode 100644 index 0000000..3e2fa33 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/oss/mapper/OSSFileMapper.java @@ -0,0 +1,8 @@ +package digital.system.jeecg.oss.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.oss.entity.OSSFile; + +public interface OSSFileMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/oss/service/IOSSFileService.java b/digital-system/src/main/java/digital/system/jeecg/oss/service/IOSSFileService.java new file mode 100644 index 0000000..b1f910b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/oss/service/IOSSFileService.java @@ -0,0 +1,15 @@ +package digital.system.jeecg.oss.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.oss.entity.OSSFile; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; + +public interface IOSSFileService extends IService { + + void upload(MultipartFile multipartFile) throws IOException; + + boolean delete(OSSFile ossFile); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/oss/service/impl/OSSFileServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/oss/service/impl/OSSFileServiceImpl.java new file mode 100644 index 0000000..dfdd938 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/oss/service/impl/OSSFileServiceImpl.java @@ -0,0 +1,41 @@ +package digital.system.jeecg.oss.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.system.jeecg.oss.entity.OSSFile; +import digital.system.jeecg.oss.mapper.OSSFileMapper; +import digital.system.jeecg.oss.service.IOSSFileService; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; +import digital.util.oss.OssBootUtil; +import digital.util.util.CommonUtils; + +import java.io.IOException; + +@Service("ossFileService") +public class OSSFileServiceImpl extends ServiceImpl implements IOSSFileService { + + @Override + public void upload(MultipartFile multipartFile) throws IOException { + String fileName = multipartFile.getOriginalFilename(); + fileName = CommonUtils.getFileName(fileName); + OSSFile ossFile = new OSSFile(); + ossFile.setFileName(fileName); + String url = OssBootUtil.upload(multipartFile,"upload/test"); + ossFile.setUrl(url); + this.save(ossFile); + } + + @Override + public boolean delete(OSSFile ossFile) { + try { + this.removeById(ossFile.getId()); + OssBootUtil.deleteUrl(ossFile.getUrl()); + } + catch (Exception ex) { + return false; + } + return true; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/DTO/UserRegisterDTO.java b/digital-system/src/main/java/digital/system/jeecg/system/DTO/UserRegisterDTO.java new file mode 100644 index 0000000..73cbcfe --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/DTO/UserRegisterDTO.java @@ -0,0 +1,23 @@ +package digital.system.jeecg.system.DTO; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * author: smcp + * date:2022-08-18 23:19 + * description: + **/ +@Data +public class UserRegisterDTO { + + @ApiModelProperty(value = "手机号") + private String phone; + + @ApiModelProperty(value = "手机验证码") + private String smscode; + + @ApiModelProperty(value = "账号") + private String username; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/DuplicateCheckController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/DuplicateCheckController.java new file mode 100644 index 0000000..c844540 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/DuplicateCheckController.java @@ -0,0 +1,87 @@ +package digital.system.jeecg.system.controller; + +import digital.system.jeecg.system.mapper.SysDictMapper; +import digital.system.jeecg.system.model.DuplicateCheckVo; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +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.RestController; +import digital.base.constant.LanguageTypeConstants; +import digital.base.constant.SymbolConstant; +import digital.base.vo.Result; +import digital.system.jeecg.system.security.DictQueryBlackListHandler; +import digital.util.util.SqlInjectionUtil; + +import javax.servlet.http.HttpServletRequest; + +/** + * @Title: DuplicateCheckAction + * @Description: 重复校验工具 + * @Author 张代浩 + * @Date 2019-03-25 + * @Version V1.0 + */ +@Slf4j +@RestController +@RequestMapping("/sys/duplicate") +@Api(tags = "重复校验") +public class DuplicateCheckController { + + @Autowired + SysDictMapper sysDictMapper; + + @Autowired + DictQueryBlackListHandler dictQueryBlackListHandler; + + /** + * 校验数据是否在系统中是否存在 + * + * @return + */ + @RequestMapping(value = "/check", method = RequestMethod.GET) + @ApiOperation("重复校验接口") + public Result doDuplicateCheck(DuplicateCheckVo duplicateCheckVo, HttpServletRequest request) { + Long num = null; + + log.info("----duplicate check------:" + duplicateCheckVo.toString()); + //关联表字典(举例:sys_user,realname,id) + //SQL注入校验(只限制非法串改数据库) + final String[] sqlInjCheck = {duplicateCheckVo.getTableName(), duplicateCheckVo.getFieldName()}; + SqlInjectionUtil.filterContent(sqlInjCheck); + // update-begin-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志 + if (StringUtils.isEmpty(duplicateCheckVo.getFieldVal())) { + Result rs = new Result(); + rs.setCode(500); + rs.setSuccess(true); + rs.setMessage("数据为空,不作处理!"); + return rs; + } + //update-begin-author:taoyan date:20220329 for: VUEN-223【安全漏洞】当前被攻击的接口 + String checkSql = duplicateCheckVo.getTableName() + SymbolConstant.COMMA + duplicateCheckVo.getFieldName() + SymbolConstant.COMMA; + if (!dictQueryBlackListHandler.isPass(checkSql)) { + return Result.error(dictQueryBlackListHandler.getError()); + } + //update-end-author:taoyan date:20220329 for: VUEN-223【安全漏洞】当前被攻击的接口 + // update-end-author:taoyan date:20211227 for: JTC-25 【online报表】oracle 操作问题 录入弹框啥都不填直接保存 ①编码不是应该提示必填么?②报错也应该是具体文字提示,不是后台错误日志 + if (StringUtils.isNotBlank(duplicateCheckVo.getDataId())) { + // [2].编辑页面校验 + num = sysDictMapper.duplicateCheckCountSql(duplicateCheckVo); + } else { + // [1].添加页面校验 + num = sysDictMapper.duplicateCheckCountSqlNoDataId(duplicateCheckVo); + } + + if (num == null || num == 0) { + // 该值可用 + return Result.ok("该值可用!"); + } else { + // 该值不可用 + log.info("该值不可用,系统中已存在!"); + return Result.error((LanguageTypeConstants.LANGUAGE_TYPE_DUPLICATE_CHECK)); + } + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCategoryController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCategoryController.java new file mode 100644 index 0000000..1c66322 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCategoryController.java @@ -0,0 +1,515 @@ +package digital.system.jeecg.system.controller; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysCategory; +import digital.system.jeecg.system.model.TreeSelectModel; +import digital.system.jeecg.system.service.ISysCategoryService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.SecurityUtils; +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import digital.base.constant.CommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.bean.jeecg.vo.DictModel; +import digital.util.util.ImportExcelUtil; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description: 分类字典 + * @Author: zita + * @Date: 2019-05-29 + * @Version: V1.0 + */ +@RestController +@RequestMapping("/sys/category") +@Slf4j +public class SysCategoryController { + @Autowired + private ISysCategoryService sysCategoryService; + + /** + * 分页列表查询 + * + * @param sysCategory + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @GetMapping(value = "/rootList") + public Result> queryPageList(SysCategory sysCategory, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + if (oConvertUtils.isEmpty(sysCategory.getPid())) { + sysCategory.setPid("0"); + } + Result> result = new Result>(); + + //--author:os_chengtgen---date:20190804 -----for: 分类字典页面显示错误,issues:377--------start + //--author:liusq---date:20211119 -----for: 【vue3】分类字典页面查询条件配置--------start + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap()); + String name = sysCategory.getName(); + String code = sysCategory.getCode(); + //QueryWrapper queryWrapper = new QueryWrapper(); + if (StringUtils.isBlank(name) && StringUtils.isBlank(code)) { + queryWrapper.eq("pid", sysCategory.getPid()); + } + //--author:liusq---date:20211119 -----for: 分类字典页面查询条件配置--------end + //--author:os_chengtgen---date:20190804 -----for:【vue3】 分类字典页面显示错误,issues:377--------end + + Page page = new Page(pageNo, pageSize); + IPage pageList = sysCategoryService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + @GetMapping(value = "/childList") + public Result> queryPageList(SysCategory sysCategory, HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, req.getParameterMap()); + List list = sysCategoryService.list(queryWrapper); + result.setSuccess(true); + result.setResult(list); + return result; + } + + + /** + * 添加 + * + * @param sysCategory + * @return + */ + @PostMapping(value = "/add") + public Result add(@RequestBody SysCategory sysCategory) { + Result result = new Result(); + try { + sysCategoryService.addSysCategory(sysCategory); + result.success("添加成功!"); + } catch (Exception e) { + log.error(e.getMessage(), e); + result.error500("操作失败"); + } + return result; + } + + /** + * 编辑 + * + * @param sysCategory + * @return + */ + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysCategory sysCategory) { + Result result = new Result(); + SysCategory sysCategoryEntity = sysCategoryService.getById(sysCategory.getId()); + if (sysCategoryEntity == null) { + result.error500("未找到对应实体"); + } else { + sysCategoryService.updateSysCategory(sysCategory); + result.success("修改成功!"); + } + return result; + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysCategory sysCategory = sysCategoryService.getById(id); + if (sysCategory == null) { + result.error500("未找到对应实体"); + } else { + this.sysCategoryService.deleteSysCategory(id); + result.success("删除成功!"); + } + + return result; + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + Result result = new Result(); + if (ids == null || "".equals(ids.trim())) { + result.error500("参数不识别!"); + } else { + this.sysCategoryService.deleteSysCategory(ids); + result.success("删除成功!"); + } + return result; + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysCategory sysCategory = sysCategoryService.getById(id); + if (sysCategory == null) { + result.error500("未找到对应实体"); + } else { + result.setResult(sysCategory); + result.setSuccess(true); + } + return result; + } + + /** + * 导出excel + * + * @param request + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysCategory sysCategory) { + // Step.1 组装查询条件查询数据 + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, request.getParameterMap()); + List pageList = sysCategoryService.list(queryWrapper); + // Step.2 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + // 过滤选中数据 + String selections = request.getParameter("selections"); + if (oConvertUtils.isEmpty(selections)) { + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + } else { + List selectionList = Arrays.asList(selections.split(",")); + List exportList = pageList.stream().filter(item -> selectionList.contains(item.getId())).collect(Collectors.toList()); + mv.addObject(NormalExcelConstants.DATA_LIST, exportList); + } + //导出文件名称 + mv.addObject(NormalExcelConstants.FILE_NAME, "分类字典列表"); + mv.addObject(NormalExcelConstants.CLASS, SysCategory.class); + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("分类字典列表数据", "导出人:" + user.getRealname(), "导出信息")); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + // 错误信息 + List errorMessage = new ArrayList<>(); + int successLines = 0, errorLines = 0; + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List listSysCategorys = ExcelImportUtil.importExcel(file.getInputStream(), SysCategory.class, params); + //按照编码长度排序 + Collections.sort(listSysCategorys); + log.info("排序后的list====>", listSysCategorys); + for (int i = 0; i < listSysCategorys.size(); i++) { + SysCategory sysCategoryExcel = listSysCategorys.get(i); + String code = sysCategoryExcel.getCode(); + if (code.length() > 3) { + String pCode = sysCategoryExcel.getCode().substring(0, code.length() - 3); + log.info("pCode====>", pCode); + String pId = sysCategoryService.queryIdByCode(pCode); + log.info("pId====>", pId); + if (StringUtils.isNotBlank(pId)) { + sysCategoryExcel.setPid(pId); + } + } else { + sysCategoryExcel.setPid("0"); + } + try { + sysCategoryService.save(sysCategoryExcel); + successLines++; + } catch (Exception e) { + errorLines++; + String message = e.getMessage().toLowerCase(); + int lineNumber = i + 1; + // 通过索引名判断出错信息 + if (message.contains(CommonConstant.SQL_INDEX_UNIQ_CATEGORY_CODE)) { + errorMessage.add("第 " + lineNumber + " 行:分类编码已经存在,忽略导入。"); + } else { + errorMessage.add("第 " + lineNumber + " 行:未知错误,忽略导入"); + log.error(e.getMessage(), e); + } + } + } + } catch (Exception e) { + errorMessage.add("发生异常:" + e.getMessage()); + log.error(e.getMessage(), e); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage); + } + + + /** + * 加载单个数据 用于回显 + */ + @RequestMapping(value = "/loadOne", method = RequestMethod.GET) + public Result loadOne(@RequestParam(name = "field") String field, @RequestParam(name = "val") String val) { + Result result = new Result(); + try { + + QueryWrapper query = new QueryWrapper(); + query.eq(field, val); + List ls = this.sysCategoryService.list(query); + if (ls == null || ls.size() == 0) { + result.setMessage("查询无果"); + result.setSuccess(false); + } else if (ls.size() > 1) { + result.setMessage("查询数据异常,[" + field + "]存在多个值:" + val); + result.setSuccess(false); + } else { + result.setSuccess(true); + result.setResult(ls.get(0)); + } + } catch (Exception e) { + e.printStackTrace(); + result.setMessage(e.getMessage()); + result.setSuccess(false); + } + return result; + } + + /** + * 加载节点的子数据 + */ + @RequestMapping(value = "/loadTreeChildren", method = RequestMethod.GET) + public Result> loadTreeChildren(@RequestParam(name = "pid") String pid) { + Result> result = new Result>(); + try { + List ls = this.sysCategoryService.queryListByPid(pid); + result.setResult(ls); + result.setSuccess(true); + } catch (Exception e) { + e.printStackTrace(); + result.setMessage(e.getMessage()); + result.setSuccess(false); + } + return result; + } + + /** + * 加载一级节点/如果是同步 则所有数据 + */ + @RequestMapping(value = "/loadTreeRoot", method = RequestMethod.GET) + public Result> loadTreeRoot(@RequestParam(name = "async") Boolean async, @RequestParam(name = "pcode") String pcode) { + Result> result = new Result>(); + try { + List ls = this.sysCategoryService.queryListByCode(pcode); + if (!async) { + loadAllCategoryChildren(ls); + } + result.setResult(ls); + result.setSuccess(true); + } catch (Exception e) { + e.printStackTrace(); + result.setMessage(e.getMessage()); + result.setSuccess(false); + } + return result; + } + + /** + * 递归求子节点 同步加载用到 + */ + private void loadAllCategoryChildren(List ls) { + for (TreeSelectModel tsm : ls) { + List temp = this.sysCategoryService.queryListByPid(tsm.getKey()); + if (temp != null && temp.size() > 0) { + tsm.setChildren(temp); + loadAllCategoryChildren(temp); + } + } + } + + /** + * 校验编码 + * + * @param pid + * @param code + * @return + */ + @GetMapping(value = "/checkCode") + public Result checkCode(@RequestParam(name = "pid", required = false) String pid, @RequestParam(name = "code", required = false) String code) { + if (oConvertUtils.isEmpty(code)) { + return Result.error("错误,类型编码为空!"); + } + if (oConvertUtils.isEmpty(pid)) { + return Result.ok(); + } + SysCategory parent = this.sysCategoryService.getById(pid); + if (code.startsWith(parent.getCode())) { + return Result.ok(); + } else { + return Result.error("编码不符合规范,须以\"" + parent.getCode() + "\"开头!"); + } + + } + + + /** + * 分类字典树控件 加载节点 + * + * @param pid + * @param pcode + * @param condition + * @return + */ + @RequestMapping(value = "/loadTreeData", method = RequestMethod.GET) + public Result> loadDict(@RequestParam(name = "pid", required = false) String pid, @RequestParam(name = "pcode", required = false) String pcode, @RequestParam(name = "condition", required = false) String condition) { + Result> result = new Result>(); + //pid如果传值了 就忽略pcode的作用 + if (oConvertUtils.isEmpty(pid)) { + if (oConvertUtils.isEmpty(pcode)) { + result.setSuccess(false); + result.setMessage("加载分类字典树参数有误.[null]!"); + return result; + } else { + if (ISysCategoryService.ROOT_PID_VALUE.equals(pcode)) { + pid = ISysCategoryService.ROOT_PID_VALUE; + } else { + pid = this.sysCategoryService.queryIdByCode(pcode); + } + if (oConvertUtils.isEmpty(pid)) { + result.setSuccess(false); + result.setMessage("加载分类字典树参数有误.[code]!"); + return result; + } + } + } + Map query = null; + if (oConvertUtils.isNotEmpty(condition)) { + query = JSON.parseObject(condition, Map.class); + } + List ls = sysCategoryService.queryListByPid(pid, query); + result.setSuccess(true); + result.setResult(ls); + return result; + } + + /** + * 分类字典控件数据回显[表单页面] + * + * @param ids + * @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身 + * @return + */ + @RequestMapping(value = "/loadDictItem", method = RequestMethod.GET) + public Result> loadDictItem(@RequestParam(name = "ids") String ids, @RequestParam(name = "delNotExist", required = false, defaultValue = "true") boolean delNotExist) { + Result> result = new Result<>(); + // 非空判断 + if (StringUtils.isBlank(ids)) { + result.setSuccess(false); + result.setMessage("ids 不能为空"); + return result; + } + // 查询数据 + List textList = sysCategoryService.loadDictItem(ids, delNotExist); + result.setSuccess(true); + result.setResult(textList); + return result; + } + + /** + * [列表页面]加载分类字典数据 用于值的替换 + * + * @param code + * @return + */ + @RequestMapping(value = "/loadAllData", method = RequestMethod.GET) + public Result> loadAllData(@RequestParam(name = "code", required = true) String code) { + Result> result = new Result>(); + LambdaQueryWrapper query = new LambdaQueryWrapper(); + if (oConvertUtils.isNotEmpty(code) && !"0".equals(code)) { + query.likeRight(SysCategory::getCode, code); + } + List list = this.sysCategoryService.list(query); + if (list == null || list.size() == 0) { + result.setMessage("无数据,参数有误.[code]"); + result.setSuccess(false); + return result; + } + List rdList = new ArrayList(); + for (SysCategory c : list) { + rdList.add(new DictModel(c.getId(), c.getName())); + } + result.setSuccess(true); + result.setResult(rdList); + return result; + } + + /** + * 根据父级id批量查询子节点 + * + * @param parentIds + * @return + */ + @GetMapping("/getChildListBatch") + public Result getChildListBatch(@RequestParam("parentIds") String parentIds) { + try { + QueryWrapper queryWrapper = new QueryWrapper<>(); + List parentIdList = Arrays.asList(parentIds.split(",")); + queryWrapper.in("pid", parentIdList); + List list = sysCategoryService.list(queryWrapper); + IPage pageList = new Page<>(1, 10, list.size()); + pageList.setRecords(list); + return Result.OK(pageList); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error("批量查询子节点失败:" + e.getMessage()); + } + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCheckRuleController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCheckRuleController.java new file mode 100644 index 0000000..cd959e6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysCheckRuleController.java @@ -0,0 +1,186 @@ +package digital.system.jeecg.system.controller; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysCheckRule; +import digital.system.jeecg.system.service.ISysCheckRuleService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import digital.base.annotation.AutoLog; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.controller.JeecgController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.Arrays; + +/** + * @Description: 编码校验规则 + * @Author: zita + * @Date: 2020-02-04 + * @Version: V1.0 + */ +@Slf4j +@Api(tags = "编码校验规则") +@RestController +@RequestMapping("/sys/checkRule") +public class SysCheckRuleController extends JeecgController { + + @Autowired + private ISysCheckRuleService sysCheckRuleService; + + /** + * 分页列表查询 + * + * @param sysCheckRule + * @param pageNo + * @param pageSize + * @param request + * @return + */ + @AutoLog(value = "编码校验规则-分页列表查询") + @ApiOperation(value = "编码校验规则-分页列表查询", notes = "编码校验规则-分页列表查询") + @GetMapping(value = "/list") + public Result queryPageList( + SysCheckRule sysCheckRule, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest request + ) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysCheckRule, request.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = sysCheckRuleService.page(page, queryWrapper); + return Result.ok(pageList); + } + + + /** + * 通过id查询 + * + * @param ruleCode + * @return + */ + @AutoLog(value = "编码校验规则-通过Code校验传入的值") + @ApiOperation(value = "编码校验规则-通过Code校验传入的值", notes = "编码校验规则-通过Code校验传入的值") + @GetMapping(value = "/checkByCode") + public Result checkByCode( + @RequestParam(name = "ruleCode") String ruleCode, + @RequestParam(name = "value") String value + ) throws UnsupportedEncodingException { + SysCheckRule sysCheckRule = sysCheckRuleService.getByCode(ruleCode); + if (sysCheckRule == null) { + return Result.error("该编码不存在"); + } + JSONObject errorResult = sysCheckRuleService.checkValue(sysCheckRule, URLDecoder.decode(value, "UTF-8")); + if (errorResult == null) { + return Result.ok(); + } else { + Result r = Result.error(errorResult.getString("message")); + r.setResult(errorResult); + return r; + } + } + + /** + * 添加 + * + * @param sysCheckRule + * @return + */ + @AutoLog(value = "编码校验规则-添加") + @ApiOperation(value = "编码校验规则-添加", notes = "编码校验规则-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody SysCheckRule sysCheckRule) { + sysCheckRuleService.save(sysCheckRule); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param sysCheckRule + * @return + */ + @AutoLog(value = "编码校验规则-编辑") + @ApiOperation(value = "编码校验规则-编辑", notes = "编码校验规则-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysCheckRule sysCheckRule) { + sysCheckRuleService.updateById(sysCheckRule); + return Result.ok("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "编码校验规则-通过id删除") + @ApiOperation(value = "编码校验规则-通过id删除", notes = "编码校验规则-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + sysCheckRuleService.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "编码校验规则-批量删除") + @ApiOperation(value = "编码校验规则-批量删除", notes = "编码校验规则-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + this.sysCheckRuleService.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @AutoLog(value = "编码校验规则-通过id查询") + @ApiOperation(value = "编码校验规则-通过id查询", notes = "编码校验规则-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + SysCheckRule sysCheckRule = sysCheckRuleService.getById(id); + return Result.ok(sysCheckRule); + } + + /** + * 导出excel + * + * @param request + * @param sysCheckRule + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysCheckRule sysCheckRule) { + return super.exportXls(request, sysCheckRule, SysCheckRule.class, "编码校验规则"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SysCheckRule.class); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataLogController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataLogController.java new file mode 100644 index 0000000..93ea342 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataLogController.java @@ -0,0 +1,96 @@ +package digital.system.jeecg.system.controller; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysDataLog; +import digital.system.jeecg.system.service.ISysDataLogService; +import lombok.extern.slf4j.Slf4j; +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 digital.base.vo.Result; + +import javax.servlet.http.HttpServletRequest; +import java.util.ArrayList; +import java.util.List; + +/** + * @Description: 系统数据日志 + * @author: smcp + */ +@RestController +@RequestMapping("/sys/dataLog") +@Slf4j +public class SysDataLogController { + @Autowired + private ISysDataLogService service; + + @RequestMapping(value = "/list", method = RequestMethod.GET) + public Result> queryPageList(SysDataLog dataLog, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(dataLog, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = service.page(page, queryWrapper); + log.info("查询当前页:" + pageList.getCurrent()); + log.info("查询当前页数量:" + pageList.getSize()); + log.info("查询结果数量:" + pageList.getRecords().size()); + log.info("数据总数:" + pageList.getTotal()); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + /** + * 查询对比数据 + * + * @param req + * @return + */ + @RequestMapping(value = "/queryCompareList", method = RequestMethod.GET) + public Result> queryCompareList(HttpServletRequest req) { + Result> result = new Result<>(); + String dataId1 = req.getParameter("dataId1"); + String dataId2 = req.getParameter("dataId2"); + List idList = new ArrayList(); + idList.add(dataId1); + idList.add(dataId2); + try { + List list = (List) service.listByIds(idList); + result.setResult(list); + result.setSuccess(true); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + /** + * 查询版本信息 + * + * @param req + * @return + */ + @RequestMapping(value = "/queryDataVerList", method = RequestMethod.GET) + public Result> queryDataVerList(HttpServletRequest req) { + Result> result = new Result<>(); + String dataTable = req.getParameter("dataTable"); + String dataId = req.getParameter("dataId"); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("data_table", dataTable); + queryWrapper.eq("data_id", dataId); + List list = service.list(queryWrapper); + if (list == null || list.size() <= 0) { + result.error500("未找到版本信息"); + } else { + result.setResult(list); + result.setSuccess(true); + } + return result; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataSourceController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataSourceController.java new file mode 100644 index 0000000..4176feb --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDataSourceController.java @@ -0,0 +1,216 @@ +//package digital.system.jeecg.system.controller; +// +//import com.alibaba.fastjson.JSONArray; +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import io.swagger.annotations.Api; +//import io.swagger.annotations.ApiOperation; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import org.springframework.web.servlet.ModelAndView; +//import digital.base.annotation.AutoLog; +//import digital.base.vo.Result; +//import digital.system.jeecg.group.base.controller.JeecgController; +//import digital.system.jeecg.group.query.QueryGenerator; +//import digital.system.jeecg.group.util.db.DataSourceCachePool; +//import digital.system.jeecg.system.entity.SysDataSource; +//import digital.system.jeecg.system.service.ISysDataSourceService; +//import digital.system.jeecg.system.util.SecurityUtil; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.util.Arrays; +//import java.util.List; +// +///** +// * @Description: 多数据源管理 +// * @Author: zita +// * @Date: 2019-12-25 +// * @Version: V1.0 +// */ +//@Slf4j +//@Api(tags = "多数据源管理") +//@RestController +//@RequestMapping("/sys/dataSource") +//public class SysDataSourceController extends JeecgController { +// +// @Autowired +// private ISysDataSourceService sysDataSourceService; +// +// /** +// * 分页列表查询 +// * +// * @param sysDataSource +// * @param pageNo +// * @param pageSize +// * @param req +// * @return +// */ +// @AutoLog(value = "多数据源管理-分页列表查询") +// @ApiOperation(value = "多数据源管理-分页列表查询", notes = "多数据源管理-分页列表查询") +// //@RequiresRoles("admin") +// @GetMapping(value = "/list") +// public Result queryPageList( +// SysDataSource sysDataSource, +// @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, +// HttpServletRequest req +// ) { +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap()); +// Page page = new Page<>(pageNo, pageSize); +// IPage pageList = sysDataSourceService.page(page, queryWrapper); +// try { +// List records = pageList.getRecords(); +// records.forEach(item -> { +// String dbPassword = item.getDbPassword(); +// if (StringUtils.isNotBlank(dbPassword)) { +// String decodedStr = SecurityUtil.jiemi(dbPassword); +// item.setDbPassword(decodedStr); +// } +// }); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return Result.ok(pageList); +// } +// +// @GetMapping(value = "/options") +// public Result queryOptions(SysDataSource sysDataSource, HttpServletRequest req) { +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysDataSource, req.getParameterMap()); +// List pageList = sysDataSourceService.list(queryWrapper); +// JSONArray array = new JSONArray(pageList.size()); +// for (SysDataSource item : pageList) { +// JSONObject option = new JSONObject(3); +// option.put("value", item.getCode()); +// option.put("label", item.getName()); +// option.put("text", item.getName()); +// array.add(option); +// } +// return Result.ok(array); +// } +// +// /** +// * 添加 +// * +// * @param sysDataSource +// * @return +// */ +// @AutoLog(value = "多数据源管理-添加") +// @ApiOperation(value = "多数据源管理-添加", notes = "多数据源管理-添加") +// @PostMapping(value = "/add") +// public Result add(@RequestBody SysDataSource sysDataSource) { +// try { +// String dbPassword = sysDataSource.getDbPassword(); +// if (StringUtils.isNotBlank(dbPassword)) { +// String encrypt = SecurityUtil.jiami(dbPassword); +// sysDataSource.setDbPassword(encrypt); +// } +// sysDataSourceService.save(sysDataSource); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return Result.ok("添加成功!"); +// } +// +// /** +// * 编辑 +// * +// * @param sysDataSource +// * @return +// */ +// @AutoLog(value = "多数据源管理-编辑") +// @ApiOperation(value = "多数据源管理-编辑", notes = "多数据源管理-编辑") +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result edit(@RequestBody SysDataSource sysDataSource) { +// try { +// SysDataSource d = sysDataSourceService.getById(sysDataSource.getId()); +// DataSourceCachePool.removeCache(d.getCode()); +// String dbPassword = sysDataSource.getDbPassword(); +// if (StringUtils.isNotBlank(dbPassword)) { +// String encrypt = SecurityUtil.jiami(dbPassword); +// sysDataSource.setDbPassword(encrypt); +// } +// sysDataSourceService.updateById(sysDataSource); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return Result.ok("编辑成功!"); +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @AutoLog(value = "多数据源管理-通过id删除") +// @ApiOperation(value = "多数据源管理-通过id删除", notes = "多数据源管理-通过id删除") +// @DeleteMapping(value = "/delete") +// public Result delete(@RequestParam(name = "id") String id) { +// SysDataSource sysDataSource = sysDataSourceService.getById(id); +// DataSourceCachePool.removeCache(sysDataSource.getCode()); +// sysDataSourceService.removeById(id); +// return Result.ok("删除成功!"); +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @AutoLog(value = "多数据源管理-批量删除") +// @ApiOperation(value = "多数据源管理-批量删除", notes = "多数据源管理-批量删除") +// @DeleteMapping(value = "/deleteBatch") +// public Result deleteBatch(@RequestParam(name = "ids") String ids) { +// List idList = Arrays.asList(ids.split(",")); +// idList.forEach(item -> { +// SysDataSource sysDataSource = sysDataSourceService.getById(item); +// DataSourceCachePool.removeCache(sysDataSource.getCode()); +// }); +// this.sysDataSourceService.removeByIds(idList); +// return Result.ok("批量删除成功!"); +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// @AutoLog(value = "多数据源管理-通过id查询") +// @ApiOperation(value = "多数据源管理-通过id查询", notes = "多数据源管理-通过id查询") +// @GetMapping(value = "/queryById") +// public Result queryById(@RequestParam(name = "id") String id) { +// SysDataSource sysDataSource = sysDataSourceService.getById(id); +// return Result.ok(sysDataSource); +// } +// +// /** +// * 导出excel +// * +// * @param request +// * @param sysDataSource +// */ +// @RequestMapping(value = "/exportXls") +// public ModelAndView exportXls(HttpServletRequest request, SysDataSource sysDataSource) { +// return super.exportXls(request, sysDataSource, SysDataSource.class, "多数据源管理"); +// } +// +// /** +// * 通过excel导入数据 +// * +// * @param request +// * @param response +// * @return +// */ +// @RequestMapping(value = "/importExcel", method = RequestMethod.POST) +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// return super.importExcel(request, response, SysDataSource.class); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictController.java new file mode 100644 index 0000000..4298317 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictController.java @@ -0,0 +1,629 @@ +//package digital.system.jeecg.system.controller; +// +// +//import com.alibaba.fastjson.JSON; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import io.swagger.annotations.Api; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.shiro.SecurityUtils; +//import org.jeecgframework.poi.excel.ExcelImportCheckUtil; +//import org.jeecgframework.poi.excel.ExcelImportUtil; +//import org.jeecgframework.poi.excel.def.NormalExcelConstants; +//import org.jeecgframework.poi.excel.entity.ExportParams; +//import org.jeecgframework.poi.excel.entity.ImportParams; +//import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +//import org.springframework.beans.BeanUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.cache.annotation.CacheEvict; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.web.bind.annotation.*; +//import org.springframework.web.multipart.MultipartFile; +//import org.springframework.web.multipart.MultipartHttpServletRequest; +//import org.springframework.web.servlet.ModelAndView; +//import digital.base.constant.CacheConstant; +//import digital.base.constant.CommonConstant; +//import digital.base.vo.LoginUser; +//import digital.base.vo.Result; +//import digital.bean.jeecg.vo.DictModel; +//import digital.bean.jeecg.vo.DictQuery; +//import digital.system.jeecg.group.query.QueryGenerator; +//import digital.system.jeecg.system.entity.SysDict; +//import digital.system.jeecg.system.entity.SysDictItem; +//import digital.system.jeecg.system.model.SysDictTree; +//import digital.system.jeecg.system.model.TreeSelectModel; +//import digital.system.jeecg.system.security.DictQueryBlackListHandler; +//import digital.system.jeecg.system.service.ISysDictItemService; +//import digital.system.jeecg.system.service.ISysDictService; +//import digital.system.jeecg.system.vo.SysDictPage; +//import digital.util.util.ImportExcelUtil; +//import digital.util.util.SqlInjectionUtil; +//import digital.util.util.oConvertUtils; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.util.*; +// +///** +// *

+// * 字典表 前端控制器 +// *

+// * +// * @Author zhangweijian +// * @since 2018-12-28 +// */ +//@Api(tags = "字典表 前端控制器") +//@RestController +//@RequestMapping("/sys/dict") +//@Slf4j +//public class SysDictController { +// +// @Autowired +// public RedisTemplate redisTemplate; +// @Autowired +// private ISysDictService sysDictService; +// @Autowired +// private ISysDictItemService sysDictItemService; +// @Autowired +// private DictQueryBlackListHandler dictQueryBlackListHandler; +// +// @RequestMapping(value = "/list", method = RequestMethod.GET) +// public Result> queryPageList(SysDict sysDict, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { +// Result> result = new Result>(); +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysDict, req.getParameterMap()); +// queryWrapper.lambda().orderByDesc(SysDict::getCreateTime); +// Page page = new Page(pageNo, pageSize); +// IPage pageList = sysDictService.page(page, queryWrapper); +// log.debug("查询当前页:" + pageList.getCurrent()); +// log.debug("查询当前页数量:" + pageList.getSize()); +// log.debug("查询结果数量:" + pageList.getRecords().size()); +// log.debug("数据总数:" + pageList.getTotal()); +// result.setSuccess(true); +// result.setResult(pageList); +// return result; +// } +// +// /** +// * @param sysDict +// * @param pageNo +// * @param pageSize +// * @param req +// * @return +// * @功能:获取树形字典数据 +// */ +// @SuppressWarnings("unchecked") +// @RequestMapping(value = "/treeList", method = RequestMethod.GET) +// public Result> treeList(SysDict sysDict, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { +// Result> result = new Result<>(); +// LambdaQueryWrapper query = new LambdaQueryWrapper<>(); +// // 构造查询条件 +// String dictName = sysDict.getDictName(); +// if (oConvertUtils.isNotEmpty(dictName)) { +// query.like(true, SysDict::getDictName, dictName); +// } +// query.orderByDesc(true, SysDict::getCreateTime); +// List list = sysDictService.list(query); +// List treeList = new ArrayList<>(); +// for (SysDict node : list) { +// treeList.add(new SysDictTree(node)); +// } +// result.setSuccess(true); +// result.setResult(treeList); +// return result; +// } +// +// /** +// * 获取全部字典数据 +// * +// * @return +// */ +// @RequestMapping(value = "/queryAllDictItems", method = RequestMethod.GET) +// public Result queryAllDictItems(HttpServletRequest request) { +// Map> res = new HashMap(5); +// res = sysDictService.queryAllDictItems(); +// return Result.ok(res); +// } +// +// /** +// * 获取字典数据 +// * +// * @param dictCode +// * @return +// */ +// @RequestMapping(value = "/getDictText/{dictCode}/{key}", method = RequestMethod.GET) +// public Result getDictText(@PathVariable("dictCode") String dictCode, @PathVariable("key") String key) { +// log.info(" dictCode : " + dictCode); +// Result result = new Result(); +// String text = null; +// try { +// text = sysDictService.queryDictTextByKey(dictCode, key); +// result.setSuccess(true); +// result.setResult(text); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// return result; +// } +// return result; +// } +// +// +// /** +// * 获取字典数据 【接口签名验证】 +// * +// * @param dictCode 字典code +// * @param dictCode 表名,文本字段,code字段 | 举例:sys_user,realname,id +// * @return +// */ +// @RequestMapping(value = "/getDictItems/{dictCode}", method = RequestMethod.GET) +// public Result> getDictItems(@PathVariable("dictCode") String dictCode, +// @RequestParam(value = "sign", required = false) String sign, +// HttpServletRequest request) { +// log.info(" dictCode ===============================: " + dictCode); +// Result> result = new Result>(); +// //update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// if (!dictQueryBlackListHandler.isPass(dictCode)) { +// return result.error500(dictQueryBlackListHandler.getError()); +// } +// //update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// try { +// List ls = sysDictService.getDictItems(dictCode); +// if (ls == null) { +// result.error500("字典Code格式不正确!"); +// return result; +// } +// result.setSuccess(true); +// result.setResult(ls); +// log.debug(result.toString()); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// return result; +// } +// return result; +// } +// +// /** +// * 【接口签名验证】 +// * 【JSearchSelectTag下拉搜索组件专用接口】 +// * 大数据量的字典表 走异步加载 即前端输入内容过滤数据 +// * +// * @param dictCode 字典code格式:table,text,code +// * @return +// */ +// @RequestMapping(value = "/loadDict/{dictCode}", method = RequestMethod.GET) +// public Result> loadDict(@PathVariable("dictCode") String dictCode, +// @RequestParam(name = "keyword", required = false) String keyword, +// @RequestParam(value = "sign", required = false) String sign, +// @RequestParam(value = "pageSize", required = false) Integer pageSize) { +// log.info(" 加载字典表数据,加载关键字: " + keyword); +// Result> result = new Result>(); +// //update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// if (!dictQueryBlackListHandler.isPass(dictCode)) { +// return result.error500(dictQueryBlackListHandler.getError()); +// } +// //update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// try { +// List ls = sysDictService.loadDict(dictCode, keyword, pageSize); +// if (ls == null) { +// result.error500("字典Code格式不正确!"); +// return result; +// } +// result.setSuccess(true); +// result.setResult(ls); +// log.info(result.toString()); +// return result; +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// return result; +// } +// } +// +// /** +// * 【接口签名验证】 +// * 【给表单设计器的表字典使用】下拉搜索模式,有值时动态拼接数据 +// * +// * @param dictCode +// * @param keyword 当前控件的值,可以逗号分割 +// * @param sign +// * @param pageSize +// * @return +// */ +// @RequestMapping(value = "/loadDictOrderByValue/{dictCode}", method = RequestMethod.GET) +// public Result> loadDictOrderByValue( +// @PathVariable("dictCode") String dictCode, +// @RequestParam(name = "keyword") String keyword, +// @RequestParam(value = "sign", required = false) String sign, +// @RequestParam(value = "pageSize", required = false) Integer pageSize) { +// // 首次查询查出来用户选中的值,并且不分页 +// Result> firstRes = this.loadDict(dictCode, keyword, sign, null); +// if (!firstRes.isSuccess()) { +// return firstRes; +// } +// // 然后再查询出第一页的数据 +// Result> result = this.loadDict(dictCode, "", sign, pageSize); +// if (!result.isSuccess()) { +// return result; +// } +// // 合并两次查询的数据 +// List firstList = firstRes.getResult(); +// List list = result.getResult(); +// for (DictModel firstItem : firstList) { +// // anyMatch 表示:判断的条件里,任意一个元素匹配成功,返回true +// // allMatch 表示:判断条件里的元素,所有的都匹配成功,返回true +// // noneMatch 跟 allMatch 相反,表示:判断条件里的元素,所有的都匹配失败,返回true +// boolean none = list.stream().noneMatch(item -> item.getValue().equals(firstItem.getValue())); +// // 当元素不存在时,再添加到集合里 +// if (none) { +// list.add(0, firstItem); +// } +// } +// return result; +// } +// +// /** +// * 【接口签名验证】 +// * 根据字典code加载字典text 返回 +// * +// * @param dictCode 顺序:tableName,text,code +// * @param keys 要查询的key +// * @param sign +// * @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身 +// * @param request +// * @return +// */ +// @RequestMapping(value = "/loadDictItem/{dictCode}", method = RequestMethod.GET) +// public Result> loadDictItem(@PathVariable("dictCode") String dictCode, @RequestParam(name = "key") String keys, @RequestParam(value = "sign", required = false) String sign, @RequestParam(value = "delNotExist", required = false, defaultValue = "true") boolean delNotExist, HttpServletRequest request) { +// Result> result = new Result<>(); +// //update-begin-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// if (!dictQueryBlackListHandler.isPass(dictCode)) { +// return result.error500(dictQueryBlackListHandler.getError()); +// } +// //update-end-author:taoyan date:20220317 for: VUEN-222【安全机制】字典接口、online报表、online图表等接口,加一些安全机制 +// try { +// if (dictCode.indexOf(",") != -1) { +// String[] params = dictCode.split(","); +// if (params.length != 3) { +// result.error500("字典Code格式不正确!"); +// return result; +// } +// List texts = sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, delNotExist); +// +// result.setSuccess(true); +// result.setResult(texts); +// log.info(result.toString()); +// } else { +// result.error500("字典Code格式不正确!"); +// } +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// return result; +// } +// +// return result; +// } +// +// /** +// * 【接口签名验证】 +// * 根据表名——显示字段-存储字段 pid 加载树形数据 +// */ +// @SuppressWarnings("unchecked") +// @RequestMapping(value = "/loadTreeData", method = RequestMethod.GET) +// public Result> loadTreeData(@RequestParam(name = "pid") String pid, @RequestParam(name = "pidField") String pidField, +// @RequestParam(name = "tableName") String tbname, +// @RequestParam(name = "text") String text, +// @RequestParam(name = "code") String code, +// @RequestParam(name = "hasChildField") String hasChildField, +// @RequestParam(name = "condition") String condition, +// @RequestParam(value = "sign", required = false) String sign, HttpServletRequest request) { +// Result> result = new Result>(); +// Map query = null; +// if (oConvertUtils.isNotEmpty(condition)) { +// query = JSON.parseObject(condition, Map.class); +// } +// // SQL注入漏洞 sign签名校验(表名,label字段,val字段,条件) +// String dictCode = tbname + "," + text + "," + code + "," + condition; +// SqlInjectionUtil.filterContent(dictCode); +// List ls = sysDictService.queryTreeList(query, tbname, text, code, pidField, pid, hasChildField); +// result.setSuccess(true); +// result.setResult(ls); +// return result; +// } +// +// /** +// * 【APP接口】根据字典配置查询表字典数据(目前暂未找到调用的地方) +// * +// * @param query +// * @param pageNo +// * @param pageSize +// * @return +// */ +// @Deprecated +// @GetMapping("/queryTableData") +// public Result> queryTableData(DictQuery query, +// @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, +// @RequestParam(value = "sign", required = false) String sign, HttpServletRequest request) { +// Result> res = new Result>(); +// // SQL注入漏洞 sign签名校验 +// String dictCode = query.getTable() + "," + query.getText() + "," + query.getCode(); +// SqlInjectionUtil.filterContent(dictCode); +// List ls = this.sysDictService.queryDictTablePageList(query, pageSize, pageNo); +// res.setResult(ls); +// res.setSuccess(true); +// return res; +// } +// +// /** +// * @param sysDict +// * @return +// * @功能:新增 +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/add", method = RequestMethod.POST) +// public Result add(@RequestBody SysDict sysDict) { +// Result result = new Result(); +// try { +// sysDict.setCreateTime(new Date()); +// sysDict.setDelFlag(CommonConstant.DEL_FLAG_0); +// sysDictService.save(sysDict); +// result.success("保存成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * @param sysDict +// * @return +// * @功能:编辑 +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result edit(@RequestBody SysDict sysDict) { +// Result result = new Result(); +// SysDict sysdict = sysDictService.getById(sysDict.getId()); +// if (sysdict == null) { +// result.error500("未找到对应实体"); +// } else { +// sysDict.setUpdateTime(new Date()); +// boolean ok = sysDictService.updateById(sysDict); +// if (ok) { +// result.success("编辑成功!"); +// } +// } +// return result; +// } +// +// /** +// * @param id +// * @return +// * @功能:删除 +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/delete", method = RequestMethod.DELETE) +// @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result(); +// boolean ok = sysDictService.removeById(id); +// if (ok) { +// result.success("删除成功!"); +// } else { +// result.error500("删除失败!"); +// } +// return result; +// } +// +// /** +// * @param ids +// * @return +// * @功能:批量删除 +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) +// @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) +// public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { +// Result result = new Result(); +// if (oConvertUtils.isEmpty(ids)) { +// result.error500("参数不识别!"); +// } else { +// sysDictService.removeByIds(Arrays.asList(ids.split(","))); +// result.success("删除成功!"); +// } +// return result; +// } +// +// /** +// * @return +// * @功能:刷新缓存 +// */ +// @RequestMapping(value = "/refleshCache") +// public Result refleshCache() { +// Result result = new Result(); +// //清空字典缓存 +// Set keys = redisTemplate.keys(CacheConstant.SYS_DICT_CACHE + "*"); +// Set keys7 = redisTemplate.keys(CacheConstant.SYS_ENABLE_DICT_CACHE + "*"); +// Set keys2 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_CACHE + "*"); +// Set keys21 = redisTemplate.keys(CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE + "*"); +// Set keys3 = redisTemplate.keys(CacheConstant.SYS_DEPARTS_CACHE + "*"); +// Set keys4 = redisTemplate.keys(CacheConstant.SYS_DEPART_IDS_CACHE + "*"); +// Set keys5 = redisTemplate.keys("jmreport:cache:dict*"); +// Set keys6 = redisTemplate.keys("jmreport:cache:dictTable*"); +// redisTemplate.delete(keys); +// redisTemplate.delete(keys2); +// redisTemplate.delete(keys21); +// redisTemplate.delete(keys3); +// redisTemplate.delete(keys4); +// redisTemplate.delete(keys5); +// redisTemplate.delete(keys6); +// redisTemplate.delete(keys7); +// return result; +// } +// +// /** +// * 导出excel +// * +// * @param request +// */ +// @RequestMapping(value = "/exportXls") +// public ModelAndView exportXls(SysDict sysDict, HttpServletRequest request) { +// // Step.1 组装查询条件 +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysDict, request.getParameterMap()); +// //Step.2 AutoPoi 导出Excel +// ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); +// List pageList = new ArrayList(); +// +// List sysDictList = sysDictService.list(queryWrapper); +// for (SysDict dictMain : sysDictList) { +// SysDictPage vo = new SysDictPage(); +// BeanUtils.copyProperties(dictMain, vo); +// // 查询机票 +// List sysDictItemList = sysDictItemService.selectItemsByMainId(dictMain.getId()); +// vo.setSysDictItemList(sysDictItemList); +// pageList.add(vo); +// } +// +// // 导出文件名称 +// mv.addObject(NormalExcelConstants.FILE_NAME, "数据字典"); +// // 注解对象Class +// mv.addObject(NormalExcelConstants.CLASS, SysDictPage.class); +// // 自定义表格参数 +// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("数据字典列表", "导出人:" + user.getRealname(), "数据字典")); +// // 导出数据列表 +// mv.addObject(NormalExcelConstants.DATA_LIST, pageList); +// return mv; +// } +// +// /** +// * 通过excel导入数据 +// * +// * @param request +// * @param +// * @return +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/importExcel", method = RequestMethod.POST) +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; +// Map fileMap = multipartRequest.getFileMap(); +// for (Map.Entry entity : fileMap.entrySet()) { +// // 获取上传文件对象 +// MultipartFile file = entity.getValue(); +// ImportParams params = new ImportParams(); +// params.setTitleRows(2); +// params.setHeadRows(2); +// params.setNeedSave(true); +// try { +// //导入Excel格式校验,看匹配的字段文本概率 +// Boolean t = ExcelImportCheckUtil.check(file.getInputStream(), SysDictPage.class, params); +// if (t != null && !t) { +// throw new RuntimeException("导入Excel校验失败 !"); +// } +// List list = ExcelImportUtil.importExcel(file.getInputStream(), SysDictPage.class, params); +// // 错误信息 +// List errorMessage = new ArrayList<>(); +// int successLines = 0, errorLines = 0; +// for (int i = 0; i < list.size(); i++) { +// SysDict po = new SysDict(); +// BeanUtils.copyProperties(list.get(i), po); +// po.setDelFlag(CommonConstant.DEL_FLAG_0); +// try { +// Integer integer = sysDictService.saveMain(po, list.get(i).getSysDictItemList()); +// if (integer > 0) { +// successLines++; +// //update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------ +// } else if (integer == -1) { +// errorLines++; +// errorMessage.add("字典名称:" + po.getDictName() + ",对应字典列表的字典项值不能为空,忽略导入。"); +// } else { +// //update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------ +// errorLines++; +// int lineNumber = i + 1; +// //update-begin---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------ +// if (oConvertUtils.isEmpty(po.getDictCode())) { +// errorMessage.add("第 " + lineNumber + " 行:字典编码不能为空,忽略导入。"); +// } else { +// errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。"); +// } +// //update-end---author:wangshuai ---date:20220209 for:[JTC-1168]字典编号不能为空------------ +// } +// } catch (Exception e) { +// errorLines++; +// int lineNumber = i + 1; +// errorMessage.add("第 " + lineNumber + " 行:字典编码已经存在,忽略导入。"); +// } +// } +// return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return Result.error("文件导入失败:" + e.getMessage()); +// } finally { +// try { +// file.getInputStream().close(); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } +// return Result.error("文件导入失败!"); +// } +// +// +// /** +// * 查询被删除的列表 +// * +// * @return +// */ +// @RequestMapping(value = "/deleteList", method = RequestMethod.GET) +// public Result> deleteList() { +// Result> result = new Result>(); +// List list = this.sysDictService.queryDeleteList(); +// result.setSuccess(true); +// result.setResult(list); +// return result; +// } +// +// /** +// * 物理删除 +// * +// * @param id +// * @return +// */ +// @RequestMapping(value = "/deletePhysic/{id}", method = RequestMethod.DELETE) +// public Result deletePhysic(@PathVariable("id") String id) { +// try { +// sysDictService.deleteOneDictPhysically(id); +// return Result.ok("删除成功!"); +// } catch (Exception e) { +// e.printStackTrace(); +// return Result.error("删除失败!"); +// } +// } +// +// /** +// * 逻辑删除的字段,进行取回 +// * +// * @param id +// * @return +// */ +// @RequestMapping(value = "/back/{id}", method = RequestMethod.PUT) +// public Result back(@PathVariable("id") String id) { +// try { +// sysDictService.updateDictDelFlag(0, id); +// return Result.ok("操作成功!"); +// } catch (Exception e) { +// e.printStackTrace(); +// return Result.error("操作失败!"); +// } +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictItemController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictItemController.java new file mode 100644 index 0000000..b41a738 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysDictItemController.java @@ -0,0 +1,178 @@ +package digital.system.jeecg.system.controller; + + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysDictItem; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.web.bind.annotation.*; +import digital.base.constant.CacheConstant; +import digital.base.vo.Result; +import digital.system.jeecg.system.service.ISysDictItemService; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; +import java.util.Date; + +/** + *

+ * 前端控制器 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Api(tags = "数据字典") +@RestController +@RequestMapping("/sys/dictItem") +@Slf4j +public class SysDictItemController { + + @Autowired + private ISysDictItemService sysDictItemService; + + /** + * @param sysDictItem + * @param pageNo + * @param pageSize + * @param req + * @return + * @功能:查询字典数据 + */ + @ApiOperation(value = "查询字典数据") + @RequestMapping(value = "/list", method = RequestMethod.GET) + public Result> queryPageList(SysDictItem sysDictItem, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysDictItem, req.getParameterMap()); + queryWrapper.orderByAsc("sort_order"); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysDictItemService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + /** + * @return + * @功能:新增 + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/add", method = RequestMethod.POST) + @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) + public Result add(@RequestBody SysDictItem sysDictItem) { + Result result = new Result(); + try { + sysDictItem.setCreateTime(new Date()); + sysDictItemService.save(sysDictItem); + result.success("保存成功!"); + } catch (Exception e) { + log.error(e.getMessage(), e); + result.error500("操作失败"); + } + return result; + } + + /** + * @param sysDictItem + * @return + * @功能:编辑 + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) + public Result edit(@RequestBody SysDictItem sysDictItem) { + Result result = new Result(); + SysDictItem sysdict = sysDictItemService.getById(sysDictItem.getId()); + if (sysdict == null) { + result.error500("未找到对应实体"); + } else { + sysDictItem.setUpdateTime(new Date()); + boolean ok = sysDictItemService.updateById(sysDictItem); + //TODO 返回false说明什么? + if (ok) { + result.success("编辑成功!"); + } + } + return result; + } + + /** + * @param id + * @return + * @功能:删除字典数据 + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/delete", method = RequestMethod.DELETE) + @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) + public Result delete(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysDictItem joinSystem = sysDictItemService.getById(id); + if (joinSystem == null) { + result.error500("未找到对应实体"); + } else { + boolean ok = sysDictItemService.removeById(id); + if (ok) { + result.success("删除成功!"); + } + } + return result; + } + + /** + * @param ids + * @return + * @功能:批量删除字典数据 + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + @CacheEvict(value = {CacheConstant.SYS_DICT_CACHE, CacheConstant.SYS_ENABLE_DICT_CACHE}, allEntries = true) + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + Result result = new Result(); + if (ids == null || "".equals(ids.trim())) { + result.error500("参数不识别!"); + } else { + this.sysDictItemService.removeByIds(Arrays.asList(ids.split(","))); + result.success("删除成功!"); + } + return result; + } + + /** + * 字典值重复校验 + * + * @param sysDictItem + * @param request + * @return + */ + @RequestMapping(value = "/dictItemCheck", method = RequestMethod.GET) + @ApiOperation("字典重复校验接口") + public Result doDictItemCheck(SysDictItem sysDictItem, HttpServletRequest request) { + Long num = Long.valueOf(0); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.eq(SysDictItem::getItemValue, sysDictItem.getItemValue()); + queryWrapper.eq(SysDictItem::getDictId, sysDictItem.getDictId()); + if (StringUtils.isNotBlank(sysDictItem.getId())) { + // 编辑页面校验 + queryWrapper.ne(SysDictItem::getId, sysDictItem.getId()); + } + num = sysDictItemService.count(queryWrapper); + if (num == 0) { + // 该值可用 + return Result.ok("该值可用!"); + } else { + // 该值不可用 + log.info("该值不可用,系统中已存在!"); + return Result.error("该值不可用,系统中已存在!"); + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysFillRuleController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysFillRuleController.java new file mode 100644 index 0000000..265139b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysFillRuleController.java @@ -0,0 +1,212 @@ +package digital.system.jeecg.system.controller; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysFillRule; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import digital.base.annotation.AutoLog; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.controller.JeecgController; +import digital.system.jeecg.system.service.ISysFillRuleService; +import digital.util.util.FillRuleUtil; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + +/** + * @Description: 填值规则 + * @Author: zita + * @Date: 2019-11-07 + * @Version: V1.0 + */ +@Slf4j +@Api(tags = "填值规则") +@RestController +@RequestMapping("/sys/fillRule") +public class SysFillRuleController extends JeecgController { + @Autowired + private ISysFillRuleService sysFillRuleService; + + /** + * 分页列表查询 + * + * @param sysFillRule + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @AutoLog(value = "填值规则-分页列表查询") + @ApiOperation(value = "填值规则-分页列表查询", notes = "填值规则-分页列表查询") + @GetMapping(value = "/list") + public Result queryPageList(SysFillRule sysFillRule, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysFillRule, req.getParameterMap()); + Page page = new Page<>(pageNo, pageSize); + IPage pageList = sysFillRuleService.page(page, queryWrapper); + return Result.ok(pageList); + } + + /** + * 测试 ruleCode + * + * @param ruleCode + * @return + */ + @GetMapping(value = "/testFillRule") + public Result testFillRule(@RequestParam("ruleCode") String ruleCode) { + Object result = FillRuleUtil.executeRule(ruleCode, new JSONObject()); + return Result.ok(result); + } + + /** + * 添加 + * + * @param sysFillRule + * @return + */ + @AutoLog(value = "填值规则-添加") + @ApiOperation(value = "填值规则-添加", notes = "填值规则-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody SysFillRule sysFillRule) { + sysFillRuleService.save(sysFillRule); + return Result.ok("添加成功!"); + } + + /** + * 编辑 + * + * @param sysFillRule + * @return + */ + @AutoLog(value = "填值规则-编辑") + @ApiOperation(value = "填值规则-编辑", notes = "填值规则-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysFillRule sysFillRule) { + sysFillRuleService.updateById(sysFillRule); + return Result.ok("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "填值规则-通过id删除") + @ApiOperation(value = "填值规则-通过id删除", notes = "填值规则-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + sysFillRuleService.removeById(id); + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "填值规则-批量删除") + @ApiOperation(value = "填值规则-批量删除", notes = "填值规则-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + this.sysFillRuleService.removeByIds(Arrays.asList(ids.split(","))); + return Result.ok("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @AutoLog(value = "填值规则-通过id查询") + @ApiOperation(value = "填值规则-通过id查询", notes = "填值规则-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + SysFillRule sysFillRule = sysFillRuleService.getById(id); + return Result.ok(sysFillRule); + } + + /** + * 导出excel + * + * @param request + * @param sysFillRule + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysFillRule sysFillRule) { + return super.exportXls(request, sysFillRule, SysFillRule.class, "填值规则"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SysFillRule.class); + } + + /** + * 通过 ruleCode 执行自定义填值规则 + * + * @param ruleCode 要执行的填值规则编码 + * @param formData 表单数据,可根据表单数据的不同生成不同的填值结果 + * @return 运行后的结果 + */ + @PutMapping("/executeRuleByCode/{ruleCode}") + public Result executeByRuleCode(@PathVariable("ruleCode") String ruleCode, @RequestBody JSONObject formData) { + Object result = FillRuleUtil.executeRule(ruleCode, formData); + return Result.ok(result); + } + + + /** + * 批量通过 ruleCode 执行自定义填值规则 + * + * @param ruleData 要执行的填值规则JSON数组: + * 示例: { "commonFormData": {}, rules: [ { "ruleCode": "xxx", "formData": null } ] } + * @return 运行后的结果,返回示例: [{"ruleCode": "order_num_rule", "result": "CN2019111117212984"}] + */ + @PutMapping("/executeRuleByCodeBatch") + public Result executeByRuleCodeBatch(@RequestBody JSONObject ruleData) { + JSONObject commonFormData = ruleData.getJSONObject("commonFormData"); + JSONArray rules = ruleData.getJSONArray("rules"); + // 遍历 rules ,批量执行规则 + JSONArray results = new JSONArray(rules.size()); + for (int i = 0; i < rules.size(); i++) { + JSONObject rule = rules.getJSONObject(i); + String ruleCode = rule.getString("ruleCode"); + JSONObject formData = rule.getJSONObject("formData"); + // 如果没有传递 formData,就用common的 + if (formData == null) { + formData = commonFormData; + } + // 执行填值规则 + Object result = FillRuleUtil.executeRule(ruleCode, formData); + JSONObject obj = new JSONObject(rules.size()); + obj.put("ruleCode", ruleCode); + obj.put("result", result); + results.add(obj); + } + return Result.ok(results); + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysGatewayRouteController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysGatewayRouteController.java new file mode 100644 index 0000000..d5d0304 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysGatewayRouteController.java @@ -0,0 +1,76 @@ +//package digital.system.jeecg.system.controller; +// +//import com.alibaba.fastjson.JSONArray; +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import io.swagger.annotations.Api; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import digital.base.vo.Result; +//import digital.system.jeecg.group.base.controller.JeecgController; +//import digital.system.jeecg.system.entity.SysGatewayRoute; +//import digital.system.jeecg.system.service.ISysGatewayRouteService; +//import digital.util.util.oConvertUtils; +// +//import java.util.List; +// +///** +// * @Description: gateway路由管理 +// * @Author: zita +// * @Date: 2020-05-26 +// * @Version: V1.0 +// */ +//@Api(tags = "gateway路由管理") +//@RestController +//@RequestMapping("/sys/gatewayRoute") +//@Slf4j +//public class SysGatewayRouteController extends JeecgController { +// +// @Autowired +// private ISysGatewayRouteService sysGatewayRouteService; +// +// @PostMapping(value = "/updateAll") +// public Result updateAll(@RequestBody JSONObject json) { +// sysGatewayRouteService.updateAll(json); +// return Result.ok("操作成功!"); +// } +// +// @GetMapping(value = "/list") +// public Result queryPageList(SysGatewayRoute sysGatewayRoute) { +// LambdaQueryWrapper query = new LambdaQueryWrapper<>(); +// List ls = sysGatewayRouteService.list(query); +// JSONArray array = new JSONArray(); +// for (SysGatewayRoute rt : ls) { +// JSONObject obj = (JSONObject) JSONObject.toJSON(rt); +// if (oConvertUtils.isNotEmpty(rt.getPredicates())) { +// obj.put("predicates", JSONArray.parseArray(rt.getPredicates())); +// } +// if (oConvertUtils.isNotEmpty(rt.getFilters())) { +// obj.put("filters", JSONArray.parseArray(rt.getFilters())); +// } +// array.add(obj); +// } +// return Result.ok(array); +// } +// +// @GetMapping(value = "/clearRedis") +// public Result clearRedis() { +// sysGatewayRouteService.clearRedis(); +// return Result.ok("清除成功!"); +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// //@RequiresRoles({"admin"}) +// @RequestMapping(value = "/delete", method = RequestMethod.DELETE) +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// sysGatewayRouteService.deleteById(id); +// return Result.ok("删除路由成功"); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysLogController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysLogController.java new file mode 100644 index 0000000..11589b2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysLogController.java @@ -0,0 +1,115 @@ +package digital.system.jeecg.system.controller; + + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysLog; +import digital.system.jeecg.system.entity.SysRole; +import lombok.extern.slf4j.Slf4j; +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 digital.base.vo.Result; +import digital.system.jeecg.system.service.ISysLogService; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.Arrays; + +/** + *

+ * 系统日志表 前端控制器 + *

+ * + * @Author zhangweijian + * @since 2018-12-26 + */ +@RestController +@RequestMapping("/sys/log") +@Slf4j +public class SysLogController { + + @Autowired + private ISysLogService sysLogService; + + /** + * @param syslog + * @param pageNo + * @param pageSize + * @param req + * @return + * @功能:查询日志记录 + */ + @RequestMapping(value = "/list", method = RequestMethod.GET) + public Result> queryPageList(SysLog syslog, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(syslog, req.getParameterMap()); + queryWrapper.lambda().orderByDesc(SysLog::getCreateTime); + Page page = new Page(pageNo, pageSize); + //日志关键词 + String keyWord = req.getParameter("keyWord"); + if (oConvertUtils.isNotEmpty(keyWord)) { + queryWrapper.like("log_content", keyWord); + } + //TODO 过滤逻辑处理 + //TODO begin、end逻辑处理 + //TODO 一个强大的功能,前端传一个字段字符串,后台只返回这些字符串对应的字段 + //创建时间/创建人的赋值 + IPage pageList = sysLogService.page(page, queryWrapper); + log.info("查询当前页:" + pageList.getCurrent()); + log.info("查询当前页数量:" + pageList.getSize()); + log.info("查询结果数量:" + pageList.getRecords().size()); + log.info("数据总数:" + pageList.getTotal()); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + /** + * @param id + * @return + * @功能:删除单个日志记录 + */ + @RequestMapping(value = "/delete", method = RequestMethod.DELETE) + public Result delete(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysLog sysLog = sysLogService.getById(id); + if (sysLog == null) { + result.error500("未找到对应实体"); + } else { + boolean ok = sysLogService.removeById(id); + if (ok) { + result.success("删除成功!"); + } + } + return result; + } + + /** + * @param ids + * @return + * @功能:批量,全部清空日志记录 + */ + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + Result result = new Result(); + if (ids == null || "".equals(ids.trim())) { + result.error500("参数不识别!"); + } else { + if ("allclear".equals(ids)) { + this.sysLogService.removeAll(); + result.success("清除成功!"); + } + this.sysLogService.removeByIds(Arrays.asList(ids.split(","))); + result.success("删除成功!"); + } + return result; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPermissionController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPermissionController.java new file mode 100644 index 0000000..5e6137b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPermissionController.java @@ -0,0 +1,936 @@ +//package digital.system.jeecg.system.controller; +// +//import com.alibaba.fastjson.JSONArray; +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.StringUtils; +//import org.apache.shiro.SecurityUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import digital.base.constant.CommonConstant; +//import digital.base.vo.LoginUser; +//import digital.base.vo.Result; +//import digital.config.JeecgBaseConfig; +//import digital.system.jeecg.group.base.service.BaseCommonService; +//import digital.system.jeecg.group.util.db.RoleIndexConfigEnum; +//import digital.system.jeecg.system.entity.SysDepartPermission; +//import digital.system.jeecg.system.entity.SysPermission; +//import digital.system.jeecg.system.entity.SysPermissionDataRule; +//import digital.system.jeecg.system.entity.SysRolePermission; +//import digital.system.jeecg.system.model.SysPermissionTree; +//import digital.system.jeecg.system.model.TreeModel; +//import digital.system.jeecg.system.service.*; +//import digital.system.jeecg.system.util.PermissionDataUtil; +//import digital.util.util.Md5Util; +//import digital.util.util.oConvertUtils; +//import digital.system.jeecg.system.service.*; +// +//import javax.servlet.http.HttpServletRequest; +//import java.util.*; +//import java.util.stream.Collectors; +// +///** +// *

+// * 菜单权限表 前端控制器 +// *

+// * +// * @Author scott +// * @since 2018-12-21 +// */ +//@Slf4j +//@RestController +//@RequestMapping("/sys/permission") +//public class SysPermissionController { +// +// @Autowired +// private ISysPermissionService sysPermissionService; +// +// @Autowired +// private ISysRolePermissionService sysRolePermissionService; +// +// @Autowired +// private ISysPermissionDataRuleService sysPermissionDataRuleService; +// +// @Autowired +// private ISysDepartPermissionService sysDepartPermissionService; +// +// @Autowired +// private ISysUserService sysUserService; +// +// @Autowired +// private JeecgBaseConfig jeecgBaseConfig; +// +// @Autowired +// private BaseCommonService baseCommonService; +// +// @Autowired +// private ISysRoleIndexService sysRoleIndexService; +// +// /** +// * 加载数据节点 +// * +// * @return +// */ +// @RequestMapping(value = "/list", method = RequestMethod.GET) +// public Result> list() { +// long start = System.currentTimeMillis(); +// Result> result = new Result<>(); +// try { +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.orderByAsc(SysPermission::getSortNo); +// List list = sysPermissionService.list(query); +// List treeList = new ArrayList<>(); +// getTreeList(treeList, list, null); +// result.setResult(treeList); +// result.setSuccess(true); +// log.info("======获取全部菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// /*update_begin author:wuxianquan date:20190908 for:先查询一级菜单,当用户点击展开菜单时加载子菜单 */ +// +// /** +// * 系统菜单列表(一级菜单) +// * +// * @return +// */ +// @RequestMapping(value = "/getSystemMenuList", method = RequestMethod.GET) +// public Result> getSystemMenuList() { +// long start = System.currentTimeMillis(); +// Result> result = new Result<>(); +// try { +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_0); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.orderByAsc(SysPermission::getSortNo); +// List list = sysPermissionService.list(query); +// List sysPermissionTreeList = new ArrayList(); +// for (SysPermission sysPermission : list) { +// SysPermissionTree sysPermissionTree = new SysPermissionTree(sysPermission); +// sysPermissionTreeList.add(sysPermissionTree); +// } +// result.setResult(sysPermissionTreeList); +// result.setSuccess(true); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// log.info("======获取一级菜单数据=====耗时:" + (System.currentTimeMillis() - start) + "毫秒"); +// return result; +// } +// +// /** +// * 查询子菜单 +// * +// * @param parentId +// * @return +// */ +// @RequestMapping(value = "/getSystemSubmenu", method = RequestMethod.GET) +// public Result> getSystemSubmenu(@RequestParam("parentId") String parentId) { +// Result> result = new Result<>(); +// try { +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// query.eq(SysPermission::getParentId, parentId); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.orderByAsc(SysPermission::getSortNo); +// List list = sysPermissionService.list(query); +// List sysPermissionTreeList = new ArrayList(); +// for (SysPermission sysPermission : list) { +// SysPermissionTree sysPermissionTree = new SysPermissionTree(sysPermission); +// sysPermissionTreeList.add(sysPermissionTree); +// } +// result.setResult(sysPermissionTreeList); +// result.setSuccess(true); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// return result; +// } +// /*update_end author:wuxianquan date:20190908 for:先查询一级菜单,当用户点击展开菜单时加载子菜单 */ +// +// // update_begin author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 ------------- +// +// /** +// * 查询子菜单 +// * +// * @param parentIds 父ID(多个采用半角逗号分割) +// * @return 返回 key-value 的 Map +// */ +// @GetMapping("/getSystemSubmenuBatch") +// public Result getSystemSubmenuBatch(@RequestParam("parentIds") String parentIds) { +// try { +// LambdaQueryWrapper query = new LambdaQueryWrapper<>(); +// List parentIdList = Arrays.asList(parentIds.split(",")); +// query.in(SysPermission::getParentId, parentIdList); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.orderByAsc(SysPermission::getSortNo); +// List list = sysPermissionService.list(query); +// Map> listMap = new HashMap(5); +// for (SysPermission item : list) { +// String pid = item.getParentId(); +// if (parentIdList.contains(pid)) { +// List mapList = listMap.get(pid); +// if (mapList == null) { +// mapList = new ArrayList<>(); +// } +// mapList.add(new SysPermissionTree(item)); +// listMap.put(pid, mapList); +// } +// } +// return Result.ok(listMap); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return Result.error("批量查询子菜单失败:" + e.getMessage()); +// } +// } +// // update_end author:sunjianlei date:20200108 for: 新增批量根据父ID查询子级菜单的接口 ------------- +// +//// /** +//// * 查询用户拥有的菜单权限和按钮权限(根据用户账号) +//// * +//// * @return +//// */ +//// @RequestMapping(value = "/queryByUser", method = RequestMethod.GET) +//// public Result queryByUser(HttpServletRequest req) { +//// Result result = new Result<>(); +//// try { +//// String username = req.getParameter("username"); +//// List metaList = sysPermissionService.queryByUser(username); +//// JSONArray jsonArray = new JSONArray(); +//// this.getPermissionJsonArray(jsonArray, metaList, null); +//// result.setResult(jsonArray); +//// result.success("查询成功"); +//// } catch (Exception e) { +//// result.error500("查询失败:" + e.getMessage()); +//// log.error(e.getMessage(), e); +//// } +//// return result; +//// } +// +// /** +// * 查询用户拥有的菜单权限和按钮权限 +// * +// * @return +// */ +// @RequestMapping(value = "/getUserPermissionByToken", method = RequestMethod.GET) +// public Result getUserPermissionByToken(HttpServletRequest request) { +// Result result = new Result(); +// try { +// //直接获取当前用户不适用前端token +// LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// if (oConvertUtils.isEmpty(loginUser)) { +// return Result.error("请登录系统!"); +// } +// List metaList = sysPermissionService.queryByUser(loginUser.getUsername()); +// //添加首页路由 +// //update-begin-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 +// if (!PermissionDataUtil.hasIndexPage(metaList)) { +// SysPermission indexMenu = sysPermissionService.list(new LambdaQueryWrapper().eq(SysPermission::getName, "首页")).get(0); +// metaList.add(0, indexMenu); +// } +// //update-end-author:taoyan date:20200211 for: TASK #3368 【路由缓存】首页的缓存设置有问题,需要根据后台的路由配置来实现是否缓存 +// +// //update-begin--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578 +// List roles = sysUserService.getRole(loginUser.getUsername()); +// String compUrl = RoleIndexConfigEnum.getIndexByRoles(roles); +// if (StringUtils.isNotBlank(compUrl)) { +// List menus = metaList.stream().filter(sysPermission -> "首页".equals(sysPermission.getName())).collect(Collectors.toList()); +// menus.get(0).setComponent(compUrl); +// } +// //update-end--Author:liusq Date:20210624 for:自定义首页地址LOWCOD-1578 +// JSONObject json = new JSONObject(); +// JSONArray menujsonArray = new JSONArray(); +// this.getPermissionJsonArray(menujsonArray, metaList, null); +// //一级菜单下的子菜单全部是隐藏路由,则一级菜单不显示 +// this.handleFirstLevelMenuHidden(menujsonArray); +// +// JSONArray authjsonArray = new JSONArray(); +// this.getAuthJsonArray(authjsonArray, metaList); +// //查询所有的权限 +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2); +// //query.eq(SysPermission::getStatus, "1"); +// List allAuthList = sysPermissionService.list(query); +// JSONArray allauthjsonArray = new JSONArray(); +// this.getAllAuthJsonArray(allauthjsonArray, allAuthList); +// //路由菜单 +// json.put("menu", menujsonArray); +// //按钮权限(用户拥有的权限集合) +// json.put("auth", authjsonArray); +// //全部权限配置集合(按钮权限,访问权限) +// json.put("allAuth", allauthjsonArray); +// json.put("sysSafeMode", jeecgBaseConfig.getSafeMode()); +// result.setResult(json); +// } catch (Exception e) { +// result.error500("查询失败:" + e.getMessage()); +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// /** +// * 【vue3专用】获取 +// * 1、查询用户拥有的按钮/表单访问权限 +// * 2、所有权限 (菜单权限配置) +// * 3、系统安全模式 (开启则online报表的数据源必填) +// */ +// @RequestMapping(value = "/getPermCode", method = RequestMethod.GET) +// public Result getPermCode() { +// try { +// // 直接获取当前用户 +// LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// if (oConvertUtils.isEmpty(loginUser)) { +// return Result.error("请登录系统!"); +// } +// // 获取当前用户的权限集合 +// List metaList = sysPermissionService.queryByUser(loginUser.getUsername()); +// // 按钮权限(用户拥有的权限集合) +// List codeList = metaList.stream() +// .filter((permission) -> CommonConstant.MENU_TYPE_2.equals(permission.getMenuType()) && CommonConstant.STATUS_1.equals(permission.getStatus())) +// .collect(ArrayList::new, (list, permission) -> list.add(permission.getPerms()), ArrayList::addAll); +// // +// JSONArray authArray = new JSONArray(); +// this.getAuthJsonArray(authArray, metaList); +// // 查询所有的权限 +// LambdaQueryWrapper query = new LambdaQueryWrapper<>(); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.eq(SysPermission::getMenuType, CommonConstant.MENU_TYPE_2); +// List allAuthList = sysPermissionService.list(query); +// JSONArray allAuthArray = new JSONArray(); +// this.getAllAuthJsonArray(allAuthArray, allAuthList); +// JSONObject result = new JSONObject(); +// // 所拥有的权限编码 +// result.put("codeList", codeList); +// //按钮权限(用户拥有的权限集合) +// result.put("auth", authArray); +// //全部权限配置集合(按钮权限,访问权限) +// result.put("allAuth", allAuthArray); +// // 系统安全模式 +// result.put("sysSafeMode", jeecgBaseConfig.getSafeMode()); +// return Result.OK(result); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return Result.error("查询失败:" + e.getMessage()); +// } +// } +// +// /** +// * 添加菜单 +// * +// * @param permission +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/add", method = RequestMethod.POST) +// public Result add(@RequestBody SysPermission permission) { +// Result result = new Result(); +// try { +// permission = PermissionDataUtil.intelligentProcessData(permission); +// sysPermissionService.addPermission(permission); +// result.success("添加成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 编辑菜单 +// * +// * @param permission +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result edit(@RequestBody SysPermission permission) { +// Result result = new Result<>(); +// try { +// permission = PermissionDataUtil.intelligentProcessData(permission); +// sysPermissionService.editPermission(permission); +// result.success("修改成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 删除菜单 +// * +// * @param id +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/delete", method = RequestMethod.DELETE) +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result<>(); +// try { +// sysPermissionService.deletePermission(id); +// result.success("删除成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500(e.getMessage()); +// } +// return result; +// } +// +// /** +// * 批量删除菜单 +// * +// * @param ids +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) +// public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { +// Result result = new Result<>(); +// try { +// String[] arr = ids.split(","); +// for (String id : arr) { +// if (oConvertUtils.isNotEmpty(id)) { +// sysPermissionService.deletePermission(id); +// } +// } +// result.success("删除成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("删除成功!"); +// } +// return result; +// } +// +// /** +// * 获取全部的权限树 +// * +// * @return +// */ +// @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET) +// public Result> queryTreeList() { +// Result> result = new Result<>(); +// // 全部权限ids +// List ids = new ArrayList<>(); +// try { +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); +// query.orderByAsc(SysPermission::getSortNo); +// List list = sysPermissionService.list(query); +// for (SysPermission sysPer : list) { +// ids.add(sysPer.getId()); +// } +// List treeList = new ArrayList<>(); +// getTreeModelList(treeList, list, null); +// +// Map resMap = new HashMap(); +// // 全部树节点数据 +// resMap.put("treeList", treeList); +// // 全部树ids +// resMap.put("ids", ids); +// result.setResult(resMap); +// result.setSuccess(true); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// /** +// * 异步加载数据节点 [接口是废的,没有用到] +// * +// * @return +// */ +// @RequestMapping(value = "/queryListAsync", method = RequestMethod.GET) +// public Result> queryAsync(@RequestParam(name = "pid", required = false) String parentId) { +// Result> result = new Result<>(); +// try { +// List list = sysPermissionService.queryListByParentId(parentId); +// if (list == null || list.size() <= 0) { +// result.error500("未找到角色信息"); +// } else { +// result.setResult(list); +// result.setSuccess(true); +// } +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// +// return result; +// } +// +// /** +// * 查询角色授权 +// * +// * @return +// */ +// @RequestMapping(value = "/queryRolePermission", method = RequestMethod.GET) +// public Result> queryRolePermission(@RequestParam(name = "roleId", required = true) String roleId) { +// Result> result = new Result<>(); +// try { +// List list = sysRolePermissionService.list(new QueryWrapper().lambda().eq(SysRolePermission::getRoleId, roleId)); +// result.setResult(list.stream().map(SysRolePermission -> String.valueOf(SysRolePermission.getPermissionId())).collect(Collectors.toList())); +// result.setSuccess(true); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// /** +// * 保存角色授权 +// * +// * @return +// */ +// @RequestMapping(value = "/saveRolePermission", method = RequestMethod.POST) +// //@RequiresRoles({ "admin" }) +// public Result saveRolePermission(@RequestBody JSONObject json) { +// long start = System.currentTimeMillis(); +// Result result = new Result<>(); +// try { +// String roleId = json.getString("roleId"); +// String permissionIds = json.getString("permissionIds"); +// String lastPermissionIds = json.getString("lastpermissionIds"); +// this.sysRolePermissionService.saveRolePermission(roleId, permissionIds, lastPermissionIds); +// //update-begin---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ +// LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// baseCommonService.addLog("修改角色ID: " + roleId + " 的权限配置,操作人: " + loginUser.getUsername(), CommonConstant.LOG_TYPE_2, 2); +// //update-end---author:wangshuai ---date:20220316 for:[VUEN-234]用户管理角色授权添加敏感日志------------ +// result.success("保存成功!"); +// log.info("======角色授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒"); +// } catch (Exception e) { +// result.error500("授权失败!"); +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// private void getTreeList(List treeList, List metaList, SysPermissionTree temp) { +// for (SysPermission permission : metaList) { +// String tempPid = permission.getParentId(); +// SysPermissionTree tree = new SysPermissionTree(permission); +// if (temp == null && oConvertUtils.isEmpty(tempPid)) { +// treeList.add(tree); +// if (!tree.getIsLeaf()) { +// getTreeList(treeList, metaList, tree); +// } +// } else if (temp != null && tempPid != null && tempPid.equals(temp.getId())) { +// temp.getChildren().add(tree); +// if (!tree.getIsLeaf()) { +// getTreeList(treeList, metaList, tree); +// } +// } +// +// } +// } +// +// private void getTreeModelList(List treeList, List metaList, TreeModel temp) { +// for (SysPermission permission : metaList) { +// String tempPid = permission.getParentId(); +// TreeModel tree = new TreeModel(permission); +// if (temp == null && oConvertUtils.isEmpty(tempPid)) { +// treeList.add(tree); +// if (!tree.getIsLeaf()) { +// getTreeModelList(treeList, metaList, tree); +// } +// } else if (temp != null && tempPid != null && tempPid.equals(temp.getKey())) { +// temp.getChildren().add(tree); +// if (!tree.getIsLeaf()) { +// getTreeModelList(treeList, metaList, tree); +// } +// } +// +// } +// } +// +// /** +// * 一级菜单的子菜单全部是隐藏路由,则一级菜单不显示 +// * +// * @param jsonArray +// */ +// private void handleFirstLevelMenuHidden(JSONArray jsonArray) { +// jsonArray = jsonArray.stream().map(obj -> { +// JSONObject returnObj = new JSONObject(); +// JSONObject jsonObj = (JSONObject) obj; +// if (jsonObj.containsKey("children")) { +// JSONArray childrens = jsonObj.getJSONArray("children"); +// childrens = childrens.stream().filter(arrObj -> !"true".equals(((JSONObject) arrObj).getString("hidden"))).collect(Collectors.toCollection(JSONArray::new)); +// if (childrens == null || childrens.size() == 0) { +// jsonObj.put("hidden", true); +// +// //vue3版本兼容代码 +// JSONObject meta = new JSONObject(); +// meta.put("hideMenu", true); +// jsonObj.put("meta", meta); +// } +// } +// return returnObj; +// }).collect(Collectors.toCollection(JSONArray::new)); +// } +// +// +// /** +// * 获取权限JSON数组 +// * +// * @param jsonArray +// * @param allList +// */ +// private void getAllAuthJsonArray(JSONArray jsonArray, List allList) { +// JSONObject json = null; +// for (SysPermission permission : allList) { +// json = new JSONObject(); +// json.put("action", permission.getPerms()); +// json.put("status", permission.getStatus()); +// //1显示2禁用 +// json.put("type", permission.getPermsType()); +// json.put("describe", permission.getName()); +// jsonArray.add(json); +// } +// } +// +// /** +// * 获取权限JSON数组 +// * +// * @param jsonArray +// * @param metaList +// */ +// private void getAuthJsonArray(JSONArray jsonArray, List metaList) { +// for (SysPermission permission : metaList) { +// if (permission.getMenuType() == null) { +// continue; +// } +// JSONObject json = null; +// if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_2) && CommonConstant.STATUS_1.equals(permission.getStatus())) { +// json = new JSONObject(); +// json.put("action", permission.getPerms()); +// json.put("type", permission.getPermsType()); +// json.put("describe", permission.getName()); +// jsonArray.add(json); +// } +// } +// } +// +// /** +// * 获取菜单JSON数组 +// * +// * @param jsonArray +// * @param metaList +// * @param parentJson +// */ +// private void getPermissionJsonArray(JSONArray jsonArray, List metaList, JSONObject parentJson) { +// for (SysPermission permission : metaList) { +// if (permission.getMenuType() == null) { +// continue; +// } +// String tempPid = permission.getParentId(); +// JSONObject json = getPermissionJsonObject(permission); +// if (json == null) { +// continue; +// } +// if (parentJson == null && oConvertUtils.isEmpty(tempPid)) { +// jsonArray.add(json); +// if (!permission.isLeaf()) { +// getPermissionJsonArray(jsonArray, metaList, json); +// } +// } else if (parentJson != null && oConvertUtils.isNotEmpty(tempPid) && tempPid.equals(parentJson.getString("id"))) { +// // 类型( 0:一级菜单 1:子菜单 2:按钮 ) +// if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)) { +// JSONObject metaJson = parentJson.getJSONObject("meta"); +// if (metaJson.containsKey("permissionList")) { +// metaJson.getJSONArray("permissionList").add(json); +// } else { +// JSONArray permissionList = new JSONArray(); +// permissionList.add(json); +// metaJson.put("permissionList", permissionList); +// } +// // 类型( 0:一级菜单 1:子菜单 2:按钮 ) +// } else if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_1) || permission.getMenuType().equals(CommonConstant.MENU_TYPE_0)) { +// if (parentJson.containsKey("children")) { +// parentJson.getJSONArray("children").add(json); +// } else { +// JSONArray children = new JSONArray(); +// children.add(json); +// parentJson.put("children", children); +// } +// +// if (!permission.isLeaf()) { +// getPermissionJsonArray(jsonArray, metaList, json); +// } +// } +// } +// +// } +// } +// +// /** +// * 根据菜单配置生成路由json +// * +// * @param permission +// * @return +// */ +// private JSONObject getPermissionJsonObject(SysPermission permission) { +// JSONObject json = new JSONObject(); +// // 类型(0:一级菜单 1:子菜单 2:按钮) +// if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_2)) { +// //json.put("action", permission.getPerms()); +// //json.put("type", permission.getPermsType()); +// //json.put("describe", permission.getName()); +// return null; +// } else if (permission.getMenuType().equals(CommonConstant.MENU_TYPE_0) || permission.getMenuType().equals(CommonConstant.MENU_TYPE_1)) { +// json.put("id", permission.getId()); +// if (permission.isRoute()) { +// //表示生成路由 +// json.put("route", "1"); +// } else { +// //表示不生成路由 +// json.put("route", "0"); +// } +// +// if (isWWWHttpUrl(permission.getUrl())) { +// json.put("path", Md5Util.md5Encode(permission.getUrl(), "utf-8")); +// } else { +// json.put("path", permission.getUrl()); +// } +// +// // 重要规则:路由name (通过URL生成路由name,路由name供前端开发,页面跳转使用) +// if (oConvertUtils.isNotEmpty(permission.getComponentName())) { +// json.put("name", permission.getComponentName()); +// } else { +// json.put("name", urlToRouteName(permission.getUrl())); +// } +// +// JSONObject meta = new JSONObject(); +// // 是否隐藏路由,默认都是显示的 +// if (permission.isHidden()) { +// json.put("hidden", true); +// //vue3版本兼容代码 +// meta.put("hideMenu", true); +// } +// // 聚合路由 +// if (permission.isAlwaysShow()) { +// json.put("alwaysShow", true); +// } +// json.put("component", permission.getComponent()); +// // 由用户设置是否缓存页面 用布尔值 +// if (permission.isKeepAlive()) { +// meta.put("keepAlive", true); +// } else { +// meta.put("keepAlive", false); +// } +// +// /*update_begin author:wuxianquan date:20190908 for:往菜单信息里添加外链菜单打开方式 */ +// //外链菜单打开方式 +// if (permission.isInternalOrExternal()) { +// meta.put("internalOrExternal", true); +// } else { +// meta.put("internalOrExternal", false); +// } +// /* update_end author:wuxianquan date:20190908 for: 往菜单信息里添加外链菜单打开方式*/ +// +// meta.put("title", permission.getName()); +// meta.put("traditionalName", permission.getTraditionalName()); +// meta.put("englishName", permission.getEnglishName()); +// +// //update-begin--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842 +// String component = permission.getComponent(); +// if (oConvertUtils.isNotEmpty(permission.getComponentName()) || oConvertUtils.isNotEmpty(component)) { +// meta.put("componentName", oConvertUtils.getString(permission.getComponentName(), component.substring(component.lastIndexOf("/") + 1))); +// } +// //update-end--Author:scott Date:20201015 for:路由缓存问题,关闭了tab页时再打开就不刷新 #842 +// +// if (oConvertUtils.isEmpty(permission.getParentId())) { +// // 一级菜单跳转地址 +// json.put("redirect", permission.getRedirect()); +// if (oConvertUtils.isNotEmpty(permission.getIcon())) { +// meta.put("icon", permission.getIcon()); +// } +// } else { +// if (oConvertUtils.isNotEmpty(permission.getIcon())) { +// meta.put("icon", permission.getIcon()); +// } +// } +// if (isWWWHttpUrl(permission.getUrl())) { +// meta.put("url", permission.getUrl()); +// } +// // update-begin--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能 +// if (permission.isHideTab()) { +// meta.put("hideTab", true); +// } +// // update-end--Author:sunjianlei Date:20210918 for:新增适配vue3项目的隐藏tab功能 +// json.put("meta", meta); +// } +// +// return json; +// } +// +// /** +// * 判断是否外网URL 例如: http://localhost:8080/jeecg-boot/swagger-ui.html#/ 支持特殊格式: {{ +// * window._CONFIG['domianURL'] }}/druid/ {{ JS代码片段 }},前台解析会自动执行JS代码片段 +// * +// * @return +// */ +// private boolean isWWWHttpUrl(String url) { +// if (url != null && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("{{"))) { +// return true; +// } +// return false; +// } +// +// /** +// * 通过URL生成路由name(去掉URL前缀斜杠,替换内容中的斜杠‘/’为-) 举例: URL = /isystem/role RouteName = +// * isystem-role +// * +// * @return +// */ +// private String urlToRouteName(String url) { +// if (oConvertUtils.isNotEmpty(url)) { +// if (url.startsWith("/")) { +// url = url.substring(1); +// } +// url = url.replace("/", "-"); +// +// // 特殊标记 +// url = url.replace(":", "@"); +// return url; +// } else { +// return null; +// } +// } +// +// /** +// * 根据菜单id来获取其对应的权限数据 +// * +// * @param sysPermissionDataRule +// * @return +// */ +// @RequestMapping(value = "/getPermRuleListByPermId", method = RequestMethod.GET) +// public Result> getPermRuleListByPermId(SysPermissionDataRule sysPermissionDataRule) { +// List permRuleList = sysPermissionDataRuleService.getPermRuleListByPermId(sysPermissionDataRule.getPermissionId()); +// Result> result = new Result<>(); +// result.setSuccess(true); +// result.setResult(permRuleList); +// return result; +// } +// +// /** +// * 添加菜单权限数据 +// * +// * @param sysPermissionDataRule +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/addPermissionRule", method = RequestMethod.POST) +// public Result addPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) { +// Result result = new Result(); +// try { +// sysPermissionDataRule.setCreateTime(new Date()); +// sysPermissionDataRuleService.savePermissionDataRule(sysPermissionDataRule); +// result.success("添加成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/editPermissionRule", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result editPermissionRule(@RequestBody SysPermissionDataRule sysPermissionDataRule) { +// Result result = new Result(); +// try { +// sysPermissionDataRuleService.saveOrUpdate(sysPermissionDataRule); +// result.success("更新成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 删除菜单权限数据 +// * +// * @param id +// * @return +// */ +// //@RequiresRoles({ "admin" }) +// @RequestMapping(value = "/deletePermissionRule", method = RequestMethod.DELETE) +// public Result deletePermissionRule(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result(); +// try { +// sysPermissionDataRuleService.deletePermissionDataRule(id); +// result.success("删除成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 查询菜单权限数据 +// * +// * @param sysPermissionDataRule +// * @return +// */ +// @RequestMapping(value = "/queryPermissionRule", method = RequestMethod.GET) +// public Result> queryPermissionRule(SysPermissionDataRule sysPermissionDataRule) { +// Result> result = new Result<>(); +// try { +// List permRuleList = sysPermissionDataRuleService.queryPermissionRule(sysPermissionDataRule); +// result.setResult(permRuleList); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 部门权限表 +// * +// * @param departId +// * @return +// */ +// @RequestMapping(value = "/queryDepartPermission", method = RequestMethod.GET) +// public Result> queryDepartPermission(@RequestParam(name = "departId", required = true) String departId) { +// Result> result = new Result<>(); +// try { +// List list = sysDepartPermissionService.list(new QueryWrapper().lambda().eq(SysDepartPermission::getDepartId, departId)); +// result.setResult(list.stream().map(SysDepartPermission -> String.valueOf(SysDepartPermission.getPermissionId())).collect(Collectors.toList())); +// result.setSuccess(true); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// } +// return result; +// } +// +// /** +// * 保存部门授权 +// * +// * @return +// */ +// @RequestMapping(value = "/saveDepartPermission", method = RequestMethod.POST) +// //@RequiresRoles({ "admin" }) +// public Result saveDepartPermission(@RequestBody JSONObject json) { +// long start = System.currentTimeMillis(); +// Result result = new Result<>(); +// try { +// String departId = json.getString("departId"); +// String permissionIds = json.getString("permissionIds"); +// String lastPermissionIds = json.getString("lastpermissionIds"); +// this.sysDepartPermissionService.saveDepartPermission(departId, permissionIds, lastPermissionIds); +// result.success("保存成功!"); +// log.info("======部门授权成功=====耗时:" + (System.currentTimeMillis() - start) + "毫秒"); +// } catch (Exception e) { +// result.error500("授权失败!"); +// log.error(e.getMessage(), e); +// } +// return result; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPositionController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPositionController.java new file mode 100644 index 0000000..16eee11 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysPositionController.java @@ -0,0 +1,282 @@ +package digital.system.jeecg.system.controller; + +import com.alibaba.fastjson.JSON; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysPosition; +import digital.system.jeecg.system.service.ISysPositionService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import digital.base.annotation.AutoLog; +import digital.base.constant.CommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.util.util.ImportExcelUtil; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +/** + * @Description: 职务表 + * @Author: zita + * @Date: 2019-09-19 + * @Version: V1.0 + */ +@Slf4j +@Api(tags = "职务表") +@RestController +@RequestMapping("/sys/position") +public class SysPositionController { + + @Autowired + private ISysPositionService sysPositionService; + + /** + * 分页列表查询 + * + * @param sysPosition + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @AutoLog(value = "职务表-分页列表查询") + @ApiOperation(value = "职务表-分页列表查询", notes = "职务表-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(SysPosition sysPosition, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysPositionService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + /** + * 添加 + * + * @param sysPosition + * @return + */ + @AutoLog(value = "职务表-添加") + @ApiOperation(value = "职务表-添加", notes = "职务表-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody SysPosition sysPosition) { + Result result = new Result(); + try { + sysPositionService.save(sysPosition); + result.success("添加成功!"); + } catch (Exception e) { + log.error(e.getMessage(), e); + result.error500("操作失败"); + } + return result; + } + + /** + * 编辑 + * + * @param sysPosition + * @return + */ + @AutoLog(value = "职务表-编辑") + @ApiOperation(value = "职务表-编辑", notes = "职务表-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysPosition sysPosition) { + Result result = new Result(); + SysPosition sysPositionEntity = sysPositionService.getById(sysPosition.getId()); + if (sysPositionEntity == null) { + result.error500("未找到对应实体"); + } else { + boolean ok = sysPositionService.updateById(sysPosition); + //TODO 返回false说明什么? + if (ok) { + result.success("修改成功!"); + } + } + + return result; + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "职务表-通过id删除") + @ApiOperation(value = "职务表-通过id删除", notes = "职务表-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + try { + sysPositionService.removeById(id); + } catch (Exception e) { + log.error("删除失败", e.getMessage()); + return Result.error("删除失败!"); + } + return Result.ok("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "职务表-批量删除") + @ApiOperation(value = "职务表-批量删除", notes = "职务表-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + Result result = new Result(); + if (ids == null || "".equals(ids.trim())) { + result.error500("参数不识别!"); + } else { + this.sysPositionService.removeByIds(Arrays.asList(ids.split(","))); + result.success("删除成功!"); + } + return result; + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @AutoLog(value = "职务表-通过id查询") + @ApiOperation(value = "职务表-通过id查询", notes = "职务表-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysPosition sysPosition = sysPositionService.getById(id); + if (sysPosition == null) { + result.error500("未找到对应实体"); + } else { + result.setResult(sysPosition); + result.setSuccess(true); + } + return result; + } + + /** + * 导出excel + * + * @param request + * @param response + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, HttpServletResponse response) { + // Step.1 组装查询条件 + QueryWrapper queryWrapper = null; + try { + String paramsStr = request.getParameter("paramsStr"); + if (oConvertUtils.isNotEmpty(paramsStr)) { + String deString = URLDecoder.decode(paramsStr, "UTF-8"); + SysPosition sysPosition = JSON.parseObject(deString, SysPosition.class); + queryWrapper = QueryGenerator.initQueryWrapper(sysPosition, request.getParameterMap()); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + //Step.2 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + List pageList = sysPositionService.list(queryWrapper); + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + //导出文件名称 + mv.addObject(NormalExcelConstants.FILE_NAME, "职务表列表"); + mv.addObject(NormalExcelConstants.CLASS, SysPosition.class); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("职务表列表数据", "导出人:" + user.getRealname(), "导出信息")); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) throws IOException { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + // 错误信息 + List errorMessage = new ArrayList<>(); + int successLines = 0, errorLines = 0; + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + List listSysPositions = ExcelImportUtil.importExcel(file.getInputStream(), SysPosition.class, params); + List list = ImportExcelUtil.importDateSave(listSysPositions, ISysPositionService.class, errorMessage, CommonConstant.SQL_INDEX_UNIQ_CODE); + errorLines += list.size(); + successLines += (listSysPositions.size() - errorLines); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error("文件导入失败:" + e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + return ImportExcelUtil.imporReturnRes(errorLines, successLines, errorMessage); + } + + /** + * 通过code查询 + * + * @param code + * @return + */ + @AutoLog(value = "职务表-通过code查询") + @ApiOperation(value = "职务表-通过code查询", notes = "职务表-通过code查询") + @GetMapping(value = "/queryByCode") + public Result queryByCode(@RequestParam(name = "code", required = true) String code) { + Result result = new Result(); + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.eq("code", code); + SysPosition sysPosition = sysPositionService.getOne(queryWrapper); + if (sysPosition == null) { + result.error500("未找到对应实体"); + } else { + result.setResult(sysPosition); + result.setSuccess(true); + } + return result; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleController.java new file mode 100644 index 0000000..e9d484b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleController.java @@ -0,0 +1,402 @@ +package digital.system.jeecg.system.controller; + + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysPermission; +import digital.system.jeecg.system.entity.SysPermissionDataRule; +import digital.system.jeecg.system.entity.SysRole; +import digital.system.jeecg.system.entity.SysRolePermission; +import digital.system.jeecg.system.model.TreeModel; +import digital.system.jeecg.system.service.ISysPermissionDataRuleService; +import digital.system.jeecg.system.service.ISysPermissionService; +import digital.system.jeecg.system.service.ISysRolePermissionService; +import digital.system.jeecg.system.service.ISysRoleService; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import digital.base.constant.CommonConstant; +import digital.base.vo.LoginUser; +import digital.base.vo.Result; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.*; + +/** + *

+ * 角色表 前端控制器 + *

+ * + * @Author scott + * @since 2018-12-19 + */ +@RestController +@RequestMapping("/sys/role") +@Slf4j +public class SysRoleController { + @Autowired + private ISysRoleService sysRoleService; + + @Autowired + private ISysPermissionDataRuleService sysPermissionDataRuleService; + + @Autowired + private ISysRolePermissionService sysRolePermissionService; + + @Autowired + private ISysPermissionService sysPermissionService; + + /** + * 分页列表查询 + * + * @param role + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @RequestMapping(value = "/list", method = RequestMethod.GET) + public Result> queryPageList(SysRole role, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + Result> result = new Result>(); + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(role, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysRoleService.page(page, queryWrapper); + result.setSuccess(true); + result.setResult(pageList); + return result; + } + + /** + * 添加 + * + * @param role + * @return + */ + @RequestMapping(value = "/add", method = RequestMethod.POST) + //@RequiresRoles({"admin"}) + public Result add(@RequestBody SysRole role) { + Result result = new Result(); + try { + role.setCreateTime(new Date()); + sysRoleService.save(role); + result.success("添加成功!"); + } catch (Exception e) { + log.error(e.getMessage(), e); + result.error500("操作失败"); + } + return result; + } + + /** + * 编辑 + * + * @param role + * @return + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysRole role) { + Result result = new Result(); + SysRole sysrole = sysRoleService.getById(role.getId()); + if (sysrole == null) { + result.error500("未找到对应实体"); + } else { + role.setUpdateTime(new Date()); + boolean ok = sysRoleService.updateById(role); + //TODO 返回false说明什么? + if (ok) { + result.success("修改成功!"); + } + } + + return result; + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/delete", method = RequestMethod.DELETE) + public Result delete(@RequestParam(name = "id", required = true) String id) { + sysRoleService.deleteRole(id); + return Result.ok("删除角色成功"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + //@RequiresRoles({"admin"}) + @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + Result result = new Result(); + if (oConvertUtils.isEmpty(ids)) { + result.error500("未选中角色!"); + } else { + sysRoleService.deleteBatchRole(ids.split(",")); + result.success("删除角色成功!"); + } + return result; + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @RequestMapping(value = "/queryById", method = RequestMethod.GET) + public Result queryById(@RequestParam(name = "id", required = true) String id) { + Result result = new Result(); + SysRole sysrole = sysRoleService.getById(id); + if (sysrole == null) { + result.error500("未找到对应实体"); + } else { + result.setResult(sysrole); + result.setSuccess(true); + } + return result; + } + + @RequestMapping(value = "/queryall", method = RequestMethod.GET) + public Result> queryall() { + Result> result = new Result<>(); + List list = sysRoleService.list(); + if (list == null || list.size() <= 0) { + result.error500("未找到角色信息"); + } else { + result.setResult(list); + result.setSuccess(true); + } + return result; + } + + /** + * 校验角色编码唯一 + */ + @RequestMapping(value = "/checkRoleCode", method = RequestMethod.GET) + public Result checkUsername(String id, String roleCode) { + Result result = new Result<>(); + //如果此参数为false则程序发生异常 + result.setResult(true); + log.info("--验证角色编码是否唯一---id:" + id + "--roleCode:" + roleCode); + try { + SysRole role = null; + if (oConvertUtils.isNotEmpty(id)) { + role = sysRoleService.getById(id); + } + SysRole newRole = sysRoleService.getOne(new QueryWrapper().lambda().eq(SysRole::getRoleCode, roleCode)); + if (newRole != null) { + //如果根据传入的roleCode查询到信息了,那么就需要做校验了。 + if (role == null) { + //role为空=>新增模式=>只要roleCode存在则返回false + result.setSuccess(false); + result.setMessage("角色编码已存在"); + return result; + } else if (!id.equals(newRole.getId())) { + //否则=>编辑模式=>判断两者ID是否一致- + result.setSuccess(false); + result.setMessage("角色编码已存在"); + return result; + } + } + } catch (Exception e) { + result.setSuccess(false); + result.setResult(false); + result.setMessage(e.getMessage()); + return result; + } + result.setSuccess(true); + return result; + } + + /** + * 导出excel + * + * @param request + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(SysRole sysRole, HttpServletRequest request) { + // Step.1 组装查询条件 + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysRole, request.getParameterMap()); + //Step.2 AutoPoi 导出Excel + ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); + List pageList = sysRoleService.list(queryWrapper); + //导出文件名称 + mv.addObject(NormalExcelConstants.FILE_NAME, "角色列表"); + mv.addObject(NormalExcelConstants.CLASS, SysRole.class); + LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + mv.addObject(NormalExcelConstants.PARAMS, new ExportParams("角色列表数据", "导出人:" + user.getRealname(), "导出信息")); + mv.addObject(NormalExcelConstants.DATA_LIST, pageList); + return mv; + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; + Map fileMap = multipartRequest.getFileMap(); + for (Map.Entry entity : fileMap.entrySet()) { + // 获取上传文件对象 + MultipartFile file = entity.getValue(); + ImportParams params = new ImportParams(); + params.setTitleRows(2); + params.setHeadRows(1); + params.setNeedSave(true); + try { + return sysRoleService.importExcelCheckRoleCode(file, params); + } catch (Exception e) { + log.error(e.getMessage(), e); + return Result.error("文件导入失败:" + e.getMessage()); + } finally { + try { + file.getInputStream().close(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + } + return Result.error("文件导入失败!"); + } + + /** + * 查询数据规则数据 + */ + @GetMapping(value = "/datarule/{permissionId}/{roleId}") + public Result loadDatarule(@PathVariable("permissionId") String permissionId, @PathVariable("roleId") String roleId) { + List list = sysPermissionDataRuleService.getPermRuleListByPermId(permissionId); + if (list == null || list.size() == 0) { + return Result.error("未找到权限配置信息"); + } else { + Map map = new HashMap(5); + map.put("datarule", list); + LambdaQueryWrapper query = new LambdaQueryWrapper() + .eq(SysRolePermission::getPermissionId, permissionId) + .isNotNull(SysRolePermission::getDataRuleIds) + .eq(SysRolePermission::getRoleId, roleId); + SysRolePermission sysRolePermission = sysRolePermissionService.getOne(query); + if (sysRolePermission == null) { + //return Result.error("未找到角色菜单配置信息"); + } else { + String drChecked = sysRolePermission.getDataRuleIds(); + if (oConvertUtils.isNotEmpty(drChecked)) { + map.put("drChecked", drChecked.endsWith(",") ? drChecked.substring(0, drChecked.length() - 1) : drChecked); + } + } + return Result.ok(map); + //TODO 以后按钮权限的查询也走这个请求 无非在map中多加两个key + } + } + + /** + * 保存数据规则至角色菜单关联表 + */ + @PostMapping(value = "/datarule") + public Result saveDatarule(@RequestBody JSONObject jsonObject) { + try { + String permissionId = jsonObject.getString("permissionId"); + String roleId = jsonObject.getString("roleId"); + String dataRuleIds = jsonObject.getString("dataRuleIds"); + log.info("保存数据规则>>" + "菜单ID:" + permissionId + "角色ID:" + roleId + "数据权限ID:" + dataRuleIds); + LambdaQueryWrapper query = new LambdaQueryWrapper() + .eq(SysRolePermission::getPermissionId, permissionId) + .eq(SysRolePermission::getRoleId, roleId); + SysRolePermission sysRolePermission = sysRolePermissionService.getOne(query); + if (sysRolePermission == null) { + return Result.error("请先保存角色菜单权限!"); + } else { + sysRolePermission.setDataRuleIds(dataRuleIds); + this.sysRolePermissionService.updateById(sysRolePermission); + } + } catch (Exception e) { + log.error("SysRoleController.saveDatarule()发生异常:" + e.getMessage(), e); + return Result.error("保存失败"); + } + return Result.ok("保存成功!"); + } + + + /** + * 用户角色授权功能,查询菜单权限树 + * + * @param request + * @return + */ + @RequestMapping(value = "/queryTreeList", method = RequestMethod.GET) + public Result> queryTreeList(HttpServletRequest request) { + Result> result = new Result<>(); + //全部权限ids + List ids = new ArrayList<>(); + try { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysPermission::getDelFlag, CommonConstant.DEL_FLAG_0); + query.orderByAsc(SysPermission::getSortNo); + List list = sysPermissionService.list(query); + for (SysPermission sysPer : list) { + ids.add(sysPer.getId()); + } + List treeList = new ArrayList<>(); + getTreeModelList(treeList, list, null); + Map resMap = new HashMap(5); + //全部树节点数据 + resMap.put("treeList", treeList); + //全部树ids + resMap.put("ids", ids); + result.setResult(resMap); + result.setSuccess(true); + } catch (Exception e) { + log.error(e.getMessage(), e); + } + return result; + } + + private void getTreeModelList(List treeList, List metaList, TreeModel temp) { + for (SysPermission permission : metaList) { + String tempPid = permission.getParentId(); + TreeModel tree = new TreeModel(permission.getId(), tempPid, permission.getName(), permission.getRuleFlag(), permission.isLeaf()); + if (temp == null && oConvertUtils.isEmpty(tempPid)) { + treeList.add(tree); + if (!tree.getIsLeaf()) { + getTreeModelList(treeList, metaList, tree); + } + } else if (temp != null && tempPid != null && tempPid.equals(temp.getKey())) { + temp.getChildren().add(tree); + if (!tree.getIsLeaf()) { + getTreeModelList(treeList, metaList, tree); + } + } + + } + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleIndexController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleIndexController.java new file mode 100644 index 0000000..2db9bb0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysRoleIndexController.java @@ -0,0 +1,166 @@ +package digital.system.jeecg.system.controller; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysRoleIndex; +import digital.system.jeecg.system.service.ISysRoleIndexService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; +import digital.base.annotation.AutoLog; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.controller.JeecgController; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Arrays; + +/** + * @Description: 角色首页配置 + * @Author: zita + * @Date: 2022-03-25 + * @Version: V1.0 + */ +@Slf4j +@Api(tags = "角色首页配置") +@RestController +@RequestMapping("/sys/sysRoleIndex") +public class SysRoleIndexController extends JeecgController { + @Autowired + private ISysRoleIndexService sysRoleIndexService; + + /** + * 分页列表查询 + * + * @param sysRoleIndex + * @param pageNo + * @param pageSize + * @param req + * @return + */ + @AutoLog(value = "角色首页配置-分页列表查询") + @ApiOperation(value = "角色首页配置-分页列表查询", notes = "角色首页配置-分页列表查询") + @GetMapping(value = "/list") + public Result queryPageList(SysRoleIndex sysRoleIndex, + @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, + @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysRoleIndex, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysRoleIndexService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param sysRoleIndex + * @return + */ + @AutoLog(value = "角色首页配置-添加") + @ApiOperation(value = "角色首页配置-添加", notes = "角色首页配置-添加") + @PostMapping(value = "/add") + public Result add(@RequestBody SysRoleIndex sysRoleIndex) { + sysRoleIndexService.save(sysRoleIndex); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param sysRoleIndex + * @return + */ + @AutoLog(value = "角色首页配置-编辑") + @ApiOperation(value = "角色首页配置-编辑", notes = "角色首页配置-编辑") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) + public Result edit(@RequestBody SysRoleIndex sysRoleIndex) { + sysRoleIndexService.updateById(sysRoleIndex); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "角色首页配置-通过id删除") + @ApiOperation(value = "角色首页配置-通过id删除", notes = "角色首页配置-通过id删除") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name = "id", required = true) String id) { + sysRoleIndexService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "角色首页配置-批量删除") + @ApiOperation(value = "角色首页配置-批量删除", notes = "角色首页配置-批量删除") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { + this.sysRoleIndexService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + @AutoLog(value = "角色首页配置-通过id查询") + @ApiOperation(value = "角色首页配置-通过id查询", notes = "角色首页配置-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name = "id", required = true) String id) { + SysRoleIndex sysRoleIndex = sysRoleIndexService.getById(id); + return Result.OK(sysRoleIndex); + } + + /** + * 导出excel + * + * @param request + * @param sysRoleIndex + */ + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysRoleIndex sysRoleIndex) { + return super.exportXls(request, sysRoleIndex, SysRoleIndex.class, "角色首页配置"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SysRoleIndex.class); + } + + /** + * 通过code查询 + * + * @param roleCode + * @return + */ + @AutoLog(value = "角色首页配置-通过code查询") + @ApiOperation(value = "角色首页配置-通过code查询", notes = "角色首页配置-通过code查询") + @GetMapping(value = "/queryByCode") + public Result queryByCode(@RequestParam(name = "roleCode", required = true) String roleCode) { + SysRoleIndex sysRoleIndex = sysRoleIndexService.getOne(new LambdaQueryWrapper().eq(SysRoleIndex::getRoleCode, roleCode)); + return Result.OK(sysRoleIndex); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysTenantController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysTenantController.java new file mode 100644 index 0000000..eb38632 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysTenantController.java @@ -0,0 +1,232 @@ +//package digital.system.jeecg.system.controller; +// +// +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.shiro.SecurityUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.web.bind.annotation.*; +//import digital.base.annotation.PermissionData; +//import digital.base.vo.LoginUser; +//import digital.base.vo.Result; +//import digital.system.jeecg.group.query.QueryGenerator; +//import digital.system.jeecg.system.entity.SysTenant; +//import digital.system.jeecg.system.service.ISysTenantService; +//import digital.util.util.oConvertUtils; +// +//import javax.servlet.http.HttpServletRequest; +//import java.util.*; +// +///** +// * 租户配置信息 +// * +// * @author: smcp +// */ +//@Slf4j +//@RestController +//@RequestMapping("/sys/tenant") +//public class SysTenantController { +// +// @Autowired +// private ISysTenantService sysTenantService; +// +// /** +// * 获取列表数据 +// * +// * @param sysTenant +// * @param pageNo +// * @param pageSize +// * @param req +// * @return +// */ +// @PermissionData(pageComponent = "system/TenantList") +// @RequestMapping(value = "/list", method = RequestMethod.GET) +// public Result> queryPageList(SysTenant sysTenant, @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest req) { +// Result> result = new Result>(); +// //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询--- +// Date beginDate = null; +// Date endDate = null; +// if (oConvertUtils.isNotEmpty(sysTenant)) { +// beginDate = sysTenant.getBeginDate(); +// endDate = sysTenant.getEndDate(); +// sysTenant.setBeginDate(null); +// sysTenant.setEndDate(null); +// } +// //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询--- +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysTenant, req.getParameterMap()); +// //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询--- +// if (oConvertUtils.isNotEmpty(sysTenant)) { +// queryWrapper.ge(oConvertUtils.isNotEmpty(beginDate), "begin_date", beginDate); +// queryWrapper.le(oConvertUtils.isNotEmpty(endDate), "end_date", endDate); +// } +// //---author:zhangyafei---date:20210916-----for: 租户管理添加日期范围查询--- +// Page page = new Page(pageNo, pageSize); +// IPage pageList = sysTenantService.page(page, queryWrapper); +// result.setSuccess(true); +// result.setResult(pageList); +// return result; +// } +// +// /** +// * 添加 +// * +// * @param +// * @return +// */ +// @RequestMapping(value = "/add", method = RequestMethod.POST) +// public Result add(@RequestBody SysTenant sysTenant) { +// Result result = new Result(); +// if (sysTenantService.getById(sysTenant.getId()) != null) { +// return result.error500("该编号已存在!"); +// } +// try { +// sysTenantService.save(sysTenant); +// result.success("添加成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 编辑 +// * +// * @param +// * @return +// */ +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result edit(@RequestBody SysTenant tenant) { +// Result result = new Result(); +// SysTenant sysTenant = sysTenantService.getById(tenant.getId()); +// if (sysTenant == null) { +// return result.error500("未找到对应实体"); +// } +// boolean ok = sysTenantService.updateById(tenant); +// if (ok) { +// result.success("修改成功!"); +// } +// return result; +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @RequestMapping(value = "/delete", method = {RequestMethod.DELETE, RequestMethod.POST}) +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// sysTenantService.removeTenantById(id); +// return Result.ok("删除成功"); +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @RequestMapping(value = "/deleteBatch", method = RequestMethod.DELETE) +// public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { +// Result result = new Result<>(); +// if (oConvertUtils.isEmpty(ids)) { +// result.error500("未选中租户!"); +// } else { +// String[] ls = ids.split(","); +// // 过滤掉已被引用的租户 +// List idList = new ArrayList<>(); +// for (String id : ls) { +// Long userCount = sysTenantService.countUserLinkTenant(id); +// if (userCount == 0) { +// idList.add(Integer.parseInt(id)); +// } +// } +// if (idList.size() > 0) { +// sysTenantService.removeByIds(idList); +// if (ls.length == idList.size()) { +// result.success("删除成功!"); +// } else { +// result.success("部分删除成功!(被引用的租户无法删除)"); +// } +// } else { +// result.error500("选择的租户都已被引用,无法删除!"); +// } +// } +// return result; +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// @RequestMapping(value = "/queryById", method = RequestMethod.GET) +// public Result queryById(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result(); +// SysTenant sysTenant = sysTenantService.getById(id); +// if (sysTenant == null) { +// result.error500("未找到对应实体"); +// } else { +// result.setResult(sysTenant); +// result.setSuccess(true); +// } +// return result; +// } +// +// +// /** +// * 查询有效的 租户数据 +// * +// * @return +// */ +// @RequestMapping(value = "/queryList", method = RequestMethod.GET) +// public Result> queryList(@RequestParam(name = "ids", required = false) String ids) { +// Result> result = new Result>(); +// LambdaQueryWrapper query = new LambdaQueryWrapper<>(); +// query.eq(SysTenant::getStatus, 1); +// if (oConvertUtils.isNotEmpty(ids)) { +// query.in(SysTenant::getId, ids.split(",")); +// } +// //此处查询忽略时间条件 +// List ls = sysTenantService.list(query); +// result.setSuccess(true); +// result.setResult(ls); +// return result; +// } +// +// /** +// * 查询当前用户的所有有效租户 【当前用于vue3版本】 +// * +// * @return +// */ +// @RequestMapping(value = "/getCurrentUserTenant", method = RequestMethod.GET) +// public Result> getCurrentUserTenant() { +// Result> result = new Result>(); +// try { +// LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +//// String tenantIds = sysUser.getRelTenantIds(); +// Map map = new HashMap(5); +//// if (oConvertUtils.isNotEmpty(tenantIds)) { +//// List tenantIdList = new ArrayList<>(); +//// for (String id : tenantIds.split(",")) { +//// tenantIdList.add(Integer.valueOf(id)); +//// } +//// // 该方法仅查询有效的租户,如果返回0个就说明所有的租户均无效。 +//// List tenantList = sysTenantService.queryEffectiveTenant(tenantIdList); +//// map.put("list", tenantList); +//// } +// result.setSuccess(true); +//// result.setResult(map); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("查询失败!"); +// } +// return result; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUploadController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUploadController.java new file mode 100644 index 0000000..9e7c99a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUploadController.java @@ -0,0 +1,69 @@ +//package digital.system.modules.system.controller; +// +//import lombok.extern.slf4j.Slf4j; +// +// +//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.RestController; +//import org.springframework.web.multipart.MultipartFile; +//import org.springframework.web.multipart.MultipartHttpServletRequest; +//import digital.base.vo.Result; +//import digital.util.exception.JeecgBootException; +//import digital.system.modules.oss.entity.OSSFile; +//import digital.system.modules.oss.service.IOSSFileService; +//import digital.util.util.CommonUtils; +//import digital.util.util.oConvertUtils; +//import javax.servlet.http.HttpServletRequest; +// +///** +// * minio文件上传示例 +// * +// * @author: smcp +// */ +//@Slf4j +//@RestController +//@RequestMapping("/sys/upload") +//public class SysUploadController { +// @Autowired +// private IOSSFileService ossFileService; +// +// /** +// * 上传 +// * +// * @param request +// */ +// @PostMapping(value = "/uploadMinio") +// public Result uploadMinio(HttpServletRequest request) { +// Result result = new Result<>(); +// String bizPath = request.getParameter("biz"); +// +// //LOWCOD-2580 sys/common/upload接口存在任意文件上传漏洞 +// if (oConvertUtils.isNotEmpty(bizPath) && (bizPath.contains("../") || bizPath.contains("..\\"))) { +// throw new JeecgBootException("上传目录bizPath,格式非法!"); +// } +// +// if (oConvertUtils.isEmpty(bizPath)) { +// bizPath = ""; +// } +// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; +// // 获取上传文件对象 +// MultipartFile file = multipartRequest.getFile("file"); +// // 获取文件名 +// String orgName = file.getOriginalFilename(); +// orgName = CommonUtils.getFileName(orgName); +// String file_url = MinioUtil.upload(file, bizPath); +// if (oConvertUtils.isEmpty(file_url)) { +// return Result.error("上传失败,请检查配置信息是否正确!"); +// } +// //保存文件信息 +// OSSFile minioFile = new OSSFile(); +// minioFile.setFileName(orgName); +// minioFile.setUrl(file_url); +// ossFileService.save(minioFile); +// result.setMessage(file_url); +// result.setSuccess(true); +// return result; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserAgentController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserAgentController.java new file mode 100644 index 0000000..86e9d0c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserAgentController.java @@ -0,0 +1,257 @@ +//package digital.system.jeecg.system.controller; +// +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +//import com.baomidou.mybatisplus.core.metadata.IPage; +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import digital.system.jeecg.group.query.QueryGenerator; +//import digital.system.jeecg.system.entity.SysUserAgent; +//import digital.system.jeecg.system.service.ISysUserAgentService; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.shiro.SecurityUtils; +//import org.jeecgframework.poi.excel.ExcelImportUtil; +//import org.jeecgframework.poi.excel.def.NormalExcelConstants; +//import org.jeecgframework.poi.excel.entity.ExportParams; +//import org.jeecgframework.poi.excel.entity.ImportParams; +//import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.beans.factory.annotation.Value; +//import org.springframework.web.bind.annotation.*; +//import org.springframework.web.multipart.MultipartFile; +//import org.springframework.web.multipart.MultipartHttpServletRequest; +//import org.springframework.web.servlet.ModelAndView; +//import digital.base.vo.LoginUser; +//import digital.base.vo.Result; +// +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import java.io.IOException; +//import java.util.Arrays; +//import java.util.List; +//import java.util.Map; +// +///** +// * @Title: Controller +// * @Description: 用户代理人设置 +// * @Author: zita +// * @Date: 2019-04-17 +// * @Version: V1.0 +// */ +//@RestController +//@RequestMapping("/sys/sysUserAgent") +//@Slf4j +//public class SysUserAgentController { +// @Autowired +// private ISysUserAgentService sysUserAgentService; +// +// @Value("${jeecg.path.upload}") +// private String upLoadPath; +// +// /** +// * 分页列表查询 +// * +// * @param sysUserAgent +// * @param pageNo +// * @param pageSize +// * @param req +// * @return +// */ +// @GetMapping(value = "/list") +// public Result> queryPageList(SysUserAgent sysUserAgent, +// @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, +// @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize, +// HttpServletRequest req) { +// Result> result = new Result>(); +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, req.getParameterMap()); +// Page page = new Page(pageNo, pageSize); +// IPage pageList = sysUserAgentService.page(page, queryWrapper); +// result.setSuccess(true); +// result.setResult(pageList); +// return result; +// } +// +// /** +// * 添加 +// * +// * @param sysUserAgent +// * @return +// */ +// @PostMapping(value = "/add") +// public Result add(@RequestBody SysUserAgent sysUserAgent) { +// Result result = new Result(); +// try { +// sysUserAgentService.save(sysUserAgent); +// result.success("代理人设置成功!"); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// result.error500("操作失败"); +// } +// return result; +// } +// +// /** +// * 编辑 +// * +// * @param sysUserAgent +// * @return +// */ +// @RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST}) +// public Result edit(@RequestBody SysUserAgent sysUserAgent) { +// Result result = new Result(); +// SysUserAgent sysUserAgentEntity = sysUserAgentService.getById(sysUserAgent.getId()); +// if (sysUserAgentEntity == null) { +// result.error500("未找到对应实体"); +// } else { +// boolean ok = sysUserAgentService.updateById(sysUserAgent); +// //TODO 返回false说明什么? +// if (ok) { +// result.success("代理人设置成功!"); +// } +// } +// +// return result; +// } +// +// /** +// * 通过id删除 +// * +// * @param id +// * @return +// */ +// @DeleteMapping(value = "/delete") +// public Result delete(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result(); +// SysUserAgent sysUserAgent = sysUserAgentService.getById(id); +// if (sysUserAgent == null) { +// result.error500("未找到对应实体"); +// } else { +// boolean ok = sysUserAgentService.removeById(id); +// if (ok) { +// result.success("删除成功!"); +// } +// } +// +// return result; +// } +// +// /** +// * 批量删除 +// * +// * @param ids +// * @return +// */ +// @DeleteMapping(value = "/deleteBatch") +// public Result deleteBatch(@RequestParam(name = "ids", required = true) String ids) { +// Result result = new Result(); +// if (ids == null || "".equals(ids.trim())) { +// result.error500("参数不识别!"); +// } else { +// this.sysUserAgentService.removeByIds(Arrays.asList(ids.split(","))); +// result.success("删除成功!"); +// } +// return result; +// } +// +// /** +// * 通过id查询 +// * +// * @param id +// * @return +// */ +// @GetMapping(value = "/queryById") +// public Result queryById(@RequestParam(name = "id", required = true) String id) { +// Result result = new Result(); +// SysUserAgent sysUserAgent = sysUserAgentService.getById(id); +// if (sysUserAgent == null) { +// result.error500("未找到对应实体"); +// } else { +// result.setResult(sysUserAgent); +// result.setSuccess(true); +// } +// return result; +// } +// +// /** +// * 通过userName查询 +// * +// * @param userName +// * @return +// */ +// @GetMapping(value = "/queryByUserName") +// public Result queryByUserName(@RequestParam(name = "userName", required = true) String userName) { +// Result result = new Result(); +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); +// queryWrapper.eq(SysUserAgent::getUserName, userName); +// SysUserAgent sysUserAgent = sysUserAgentService.getOne(queryWrapper); +// if (sysUserAgent == null) { +// result.error500("未找到对应实体"); +// } else { +// result.setResult(sysUserAgent); +// result.setSuccess(true); +// } +// return result; +// } +// +// /** +// * 导出excel +// * +// * @param sysUserAgent +// * @param request +// */ +// @RequestMapping(value = "/exportXls") +// public ModelAndView exportXls(SysUserAgent sysUserAgent, HttpServletRequest request) { +// // Step.1 组装查询条件 +// QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysUserAgent, request.getParameterMap()); +// //Step.2 AutoPoi 导出Excel +// ModelAndView mv = new ModelAndView(new JeecgEntityExcelView()); +// List pageList = sysUserAgentService.list(queryWrapper); +// //导出文件名称 +// mv.addObject(NormalExcelConstants.FILE_NAME, "用户代理人设置列表"); +// mv.addObject(NormalExcelConstants.CLASS, SysUserAgent.class); +// LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// ExportParams exportParams = new ExportParams("用户代理人设置列表数据", "导出人:" + user.getRealname(), "导出信息"); +// exportParams.setImageBasePath(upLoadPath); +// mv.addObject(NormalExcelConstants.PARAMS, exportParams); +// mv.addObject(NormalExcelConstants.DATA_LIST, pageList); +// return mv; +// } +// +// /** +// * 通过excel导入数据 +// * +// * @param request +// * @param response +// * @return +// */ +// @RequestMapping(value = "/importExcel", method = RequestMethod.POST) +// public Result importExcel(HttpServletRequest request, HttpServletResponse response) { +// MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request; +// Map fileMap = multipartRequest.getFileMap(); +// for (Map.Entry entity : fileMap.entrySet()) { +// // 获取上传文件对象 +// MultipartFile file = entity.getValue(); +// ImportParams params = new ImportParams(); +// params.setTitleRows(2); +// params.setHeadRows(1); +// params.setNeedSave(true); +// try { +// List listSysUserAgents = ExcelImportUtil.importExcel(file.getInputStream(), SysUserAgent.class, params); +// for (SysUserAgent sysUserAgentExcel : listSysUserAgents) { +// sysUserAgentService.save(sysUserAgentExcel); +// } +// return Result.ok("文件导入成功!数据行数:" + listSysUserAgents.size()); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// return Result.error("文件导入失败!"); +// } finally { +// try { +// file.getInputStream().close(); +// } catch (IOException e) { +// e.printStackTrace(); +// } +// } +// } +// return Result.error("文件导入失败!"); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserOnlineController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserOnlineController.java new file mode 100644 index 0000000..2e7af10 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysUserOnlineController.java @@ -0,0 +1,105 @@ +//package digital.system.jeecg.system.controller; +// +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import lombok.extern.slf4j.Slf4j; +//import org.apache.commons.lang3.StringUtils; +//import org.apache.shiro.SecurityUtils; +//import org.springframework.beans.BeanUtils; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.web.bind.annotation.*; +//import digital.base.constant.CacheConstant; +//import digital.base.constant.CommonConstant; +//import digital.base.constant.LanguageTypeConstants; +//import digital.base.vo.LoginUser; +//import digital.base.vo.Result; +//import digital.system.jeecg.group.base.service.BaseCommonService; +//import digital.system.jeecg.system.service.ISysUserService; +//import digital.system.jeecg.system.service.impl.SysBaseApiImpl; +//import digital.system.jeecg.system.vo.SysUserOnlineVO; +//import digital.util.util.JeecgRedisUtil; +//import digital.util.util.JwtUtil; +//import digital.util.util.oConvertUtils; +// +//import javax.annotation.Resource; +//import java.util.ArrayList; +//import java.util.Collection; +//import java.util.Collections; +//import java.util.List; +// +///** +// * @Description: 在线用户 +// * @Author: chenli +// * @Date: 2020-06-07 +// * @Version: V1.0 +// */ +//@RestController +//@RequestMapping("/sys/online") +//@Slf4j +//public class SysUserOnlineController { +// +// @Autowired +// public RedisTemplate redisTemplate; +// @Autowired +// public ISysUserService userService; +// @Autowired +// private JeecgRedisUtil jeecgRedisUtil; +// @Autowired +// private SysBaseApiImpl sysBaseApi; +// +// @Resource +// private BaseCommonService baseCommonService; +// +// @RequestMapping(value = "/list", method = RequestMethod.GET) +// public Result> list(@RequestParam(name = "username", required = false) String username, +// @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) { +// Collection keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*"); +// List onlineList = new ArrayList(); +// for (String key : keys) { +// String token = (String) jeecgRedisUtil.get(key); +// if (StringUtils.isNotEmpty(token)) { +// SysUserOnlineVO online = new SysUserOnlineVO(); +// online.setToken(token); +// //TODO 改成一次性查询 +// LoginUser loginUser = sysBaseApi.getUserByName(JwtUtil.getUsername(token)); +// if (loginUser != null) { +// //update-begin---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------ +// //验证用户名是否与传过来的用户名相同 +// boolean isMatchUsername = true; +// //判断用户名是否为空,并且当前循环的用户不包含传过来的用户名,那么就设成false +// if (oConvertUtils.isNotEmpty(username) && !loginUser.getUsername().contains(username)) { +// isMatchUsername = false; +// } +// if (isMatchUsername) { +// BeanUtils.copyProperties(loginUser, online); +// onlineList.add(online); +// } +// //update-end---author:wangshuai ---date:20220104 for:[JTC-382]在线用户查询无效------------ +// } +// } +// } +// Collections.reverse(onlineList); +// +// Page page = new Page(pageNo, pageSize); +// int count = onlineList.size(); +// List pages = new ArrayList<>(); +// // 计算当前页第一条数据的下标 +// int currId = pageNo > 1 ? (pageNo - 1) * pageSize : 0; +// for (int i = 0; i < pageSize && i < count - currId; i++) { +// pages.add(onlineList.get(currId + i)); +// } +// page.setSize(pageSize); +// page.setCurrent(pageNo); +// page.setTotal(count); +// // 计算分页总页数 +// page.setPages(count % 10 == 0 ? count / 10 : count / 10 + 1); +// page.setRecords(pages); +// +// Result> result = new Result>(); +// result.setSuccess(true); +// result.setResult(page); +// return result; +// } +// +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/controller/SysVersionController.java b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysVersionController.java new file mode 100644 index 0000000..4e23a66 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/controller/SysVersionController.java @@ -0,0 +1,177 @@ +package digital.system.jeecg.system.controller; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.base.annotation.AutoLog; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.controller.JeecgController; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysVersion; +import digital.system.jeecg.system.service.ISysVersionService; +import lombok.extern.slf4j.Slf4j; + +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.def.NormalExcelConstants; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.apache.shiro.authz.annotation.RequiresPermissions; + + /** + * @Description: sys_version + * @Author: jeecg-boot + * @Date: 2024-03-07 + * @Version: V1.0 + */ +@Api(tags="sys_version") +@RestController +@RequestMapping("/sysVersion/sysVersion") +@Slf4j +public class SysVersionController extends JeecgController { + @Autowired + private ISysVersionService sysVersionService; + + /** + * 分页列表查询 + * + * @param sysVersion + * @param pageNo + * @param pageSize + * @param req + * @return + */ + //@AutoLog(value = "sys_version-分页列表查询") + @ApiOperation(value="sys_version-分页列表查询", notes="sys_version-分页列表查询") + @GetMapping(value = "/list") + public Result> queryPageList(SysVersion sysVersion, + @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, + @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, + HttpServletRequest req) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(sysVersion, req.getParameterMap()); + Page page = new Page(pageNo, pageSize); + IPage pageList = sysVersionService.page(page, queryWrapper); + return Result.OK(pageList); + } + + /** + * 添加 + * + * @param sysVersion + * @return + */ + @AutoLog(value = "sys_version-添加") + @ApiOperation(value="sys_version-添加", notes="sys_version-添加") + @RequiresPermissions("sysVersion:sys_version:add") + @PostMapping(value = "/add") + public Result add(@RequestBody SysVersion sysVersion) { + sysVersionService.save(sysVersion); + return Result.OK("添加成功!"); + } + + /** + * 编辑 + * + * @param sysVersion + * @return + */ + @AutoLog(value = "sys_version-编辑") + @ApiOperation(value="sys_version-编辑", notes="sys_version-编辑") + @RequiresPermissions("sysVersion:sys_version:edit") + @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) + public Result edit(@RequestBody SysVersion sysVersion) { + sysVersionService.updateById(sysVersion); + return Result.OK("编辑成功!"); + } + + /** + * 通过id删除 + * + * @param id + * @return + */ + @AutoLog(value = "sys_version-通过id删除") + @ApiOperation(value="sys_version-通过id删除", notes="sys_version-通过id删除") + @RequiresPermissions("sysVersion:sys_version:delete") + @DeleteMapping(value = "/delete") + public Result delete(@RequestParam(name="id",required=true) String id) { + sysVersionService.removeById(id); + return Result.OK("删除成功!"); + } + + /** + * 批量删除 + * + * @param ids + * @return + */ + @AutoLog(value = "sys_version-批量删除") + @ApiOperation(value="sys_version-批量删除", notes="sys_version-批量删除") + @RequiresPermissions("sysVersion:sys_version:deleteBatch") + @DeleteMapping(value = "/deleteBatch") + public Result deleteBatch(@RequestParam(name="ids",required=true) String ids) { + this.sysVersionService.removeByIds(Arrays.asList(ids.split(","))); + return Result.OK("批量删除成功!"); + } + + /** + * 通过id查询 + * + * @param id + * @return + */ + //@AutoLog(value = "sys_version-通过id查询") + @ApiOperation(value="sys_version-通过id查询", notes="sys_version-通过id查询") + @GetMapping(value = "/queryById") + public Result queryById(@RequestParam(name="id",required=true) String id) { + SysVersion sysVersion = sysVersionService.getById(id); + if(sysVersion==null) { + return Result.error("未找到对应数据"); + } + return Result.OK(sysVersion); + } + + /** + * 导出excel + * + * @param request + * @param sysVersion + */ + @RequiresPermissions("sysVersion:sys_version:exportXls") + @RequestMapping(value = "/exportXls") + public ModelAndView exportXls(HttpServletRequest request, SysVersion sysVersion) { + return super.exportXls(request, sysVersion, SysVersion.class, "sys_version"); + } + + /** + * 通过excel导入数据 + * + * @param request + * @param response + * @return + */ + @RequiresPermissions("sysVersion:sys_version:importExcel") + @RequestMapping(value = "/importExcel", method = RequestMethod.POST) + public Result importExcel(HttpServletRequest request, HttpServletResponse response) { + return super.importExcel(request, response, SysVersion.class); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncement.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncement.java new file mode 100644 index 0000000..fd744a4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncement.java @@ -0,0 +1,150 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.io.Serializable; + +/** + * @Description: 系统通告表 + * @Author: zita + * @Date: 2019-01-02 + * @Version: V1.0 + */ +@Data +@TableName("sys_announcement") +public class SysAnnouncement implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private java.lang.String id; + /** + * 标题 + */ + @Excel(name = "标题", width = 15) + private java.lang.String titile; + /** + * 内容 + */ + @Excel(name = "内容", width = 30) + private java.lang.String msgContent; + /** + * 开始时间 + */ + @Excel(name = "开始时间", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date startTime; + /** + * 结束时间 + */ + @Excel(name = "结束时间", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date endTime; + /** + * 发布人 + */ + @Excel(name = "发布人", width = 15) + private java.lang.String sender; + /** + * 优先级(L低,M中,H高) + */ + @Excel(name = "优先级", width = 15, dicCode = "priority") + @Dict(dicCode = "priority") + private java.lang.String priority; + + /** + * 消息类型1:通知公告2:系统消息 + */ + @Excel(name = "消息类型", width = 15, dicCode = "msg_category") + @Dict(dicCode = "msg_category") + private java.lang.String msgCategory; + /** + * 通告对象类型(USER:指定用户,ALL:全体用户) + */ + @Excel(name = "通告对象类型", width = 15, dicCode = "msg_type") + @Dict(dicCode = "msg_type") + private java.lang.String msgType; + /** + * 发布状态(0未发布,1已发布,2已撤销) + */ + @Excel(name = "发布状态", width = 15, dicCode = "send_status") + @Dict(dicCode = "send_status") + private java.lang.String sendStatus; + /** + * 发布时间 + */ + @Excel(name = "发布时间", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date sendTime; + /** + * 撤销时间 + */ + @Excel(name = "撤销时间", width = 15, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date cancelTime; + /** + * 删除状态(0,正常,1已删除) + */ + private java.lang.String delFlag; + /** + * 创建人 + */ + private java.lang.String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + /** + * 更新人 + */ + private java.lang.String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; + /** + * 指定用户 + **/ + private java.lang.String userIds; + /** + * 业务类型(email:邮件 bpm:流程) + */ + private java.lang.String busType; + /** + * 业务id + */ + private java.lang.String busId; + /** + * 打开方式 组件:component 路由:url + */ + private java.lang.String openType; + /** + * 组件/路由 地址 + */ + private java.lang.String openPage; + /** + * 摘要 + */ + private java.lang.String msgAbstract; + /** + * 钉钉task_id,用于撤回消息 + */ + private java.lang.String dtTaskId; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncementSend.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncementSend.java new file mode 100644 index 0000000..21ca3f6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysAnnouncementSend.java @@ -0,0 +1,66 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: 用户通告阅读标记表 + * @Author: zita + * @Date: 2019-02-21 + * @Version: V1.0 + */ +@Data +@TableName("sys_announcement_send") +public class SysAnnouncementSend implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private java.lang.String id; + /** + * 通告id + */ + private java.lang.String anntId; + /** + * 用户id + */ + private java.lang.String userId; + /** + * 阅读状态(0未读,1已读) + */ + private java.lang.String readFlag; + /** + * 阅读时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date readTime; + /** + * 创建人 + */ + private java.lang.String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + /** + * 更新人 + */ + private java.lang.String updateBy; + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCategory.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCategory.java new file mode 100644 index 0000000..c392249 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCategory.java @@ -0,0 +1,87 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: 分类字典 + * @Author: zita + * @Date: 2019-05-29 + * @Version: V1.0 + */ +@Data +@TableName("sys_category") +public class SysCategory implements Serializable, Comparable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + private java.lang.String id; + /** + * 父级节点 + */ + private java.lang.String pid; + /** + * 类型名称 + */ + @Excel(name = "类型名称", width = 15) + private java.lang.String name; + /** + * 类型编码 + */ + @Excel(name = "类型编码", width = 15) + private java.lang.String code; + /** + * 创建人 + */ + private java.lang.String createBy; + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + /** + * 更新人 + */ + private java.lang.String updateBy; + /** + * 更新日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; + /** + * 所属部门 + */ + private java.lang.String sysOrgCode; + /** + * 是否有子节点 + */ + @Excel(name = "是否有子节点(1:有)", width = 15) + private java.lang.String hasChild; + + @Override + public int compareTo(SysCategory o) { + //比较条件我们定的是按照code的长度升序 + // <0:当前对象比传入对象小。 + // =0:当前对象等于传入对象。 + // >0:当前对象比传入对象大。 + int s = this.code.length() - o.code.length(); + return s; + } + + @Override + public String toString() { + return "SysCategory [code=" + code + ", name=" + name + "]"; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCheckRule.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCheckRule.java new file mode 100644 index 0000000..06de2c6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysCheckRule.java @@ -0,0 +1,88 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.util.Date; + +/** + * @Description: 编码校验规则 + * @Author: zita + * @Date: 2020-02-04 + * @Version: V1.0 + */ +@Data +@TableName("sys_check_rule") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_check_rule对象", description = "编码校验规则") +public class SysCheckRule { + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键id") + private String id; + /** + * 规则名称 + */ + @Excel(name = "规则名称", width = 15) + @ApiModelProperty(value = "规则名称") + private String ruleName; + /** + * 规则Code + */ + @Excel(name = "规则Code", width = 15) + @ApiModelProperty(value = "规则Code") + private String ruleCode; + /** + * 规则JSON + */ + @Excel(name = "规则JSON", width = 15) + @ApiModelProperty(value = "规则JSON") + private String ruleJson; + /** + * 规则描述 + */ + @Excel(name = "规则描述", width = 15) + @ApiModelProperty(value = "规则描述") + private String ruleDescription; + /** + * 更新人 + */ + @Excel(name = "更新人", width = 15) + @ApiModelProperty(value = "更新人") + private String updateBy; + /** + * 更新时间 + */ + @Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private Date updateTime; + /** + * 创建人 + */ + @Excel(name = "创建人", width = 15) + @ApiModelProperty(value = "创建人") + private String createBy; + /** + * 创建时间 + */ + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private Date createTime; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataLog.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataLog.java new file mode 100644 index 0000000..0620c5e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataLog.java @@ -0,0 +1,73 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: 系统数据日志 + * @author: smcp + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysDataLog implements Serializable { + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + /** + * id + */ + private String id; + + /** + * 创建人登录名称 + */ + private String createBy; + + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新人登录名称 + */ + private String updateBy; + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + + /** + * 更新日期 + */ + private Date updateTime; + + /** + * 表名 + */ + private String dataTable; + + /** + * 数据ID + */ + private String dataId; + + /** + * 数据内容 + */ + private String dataContent; + + /** + * 版本号 + */ + private String dataVersion; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataSource.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataSource.java new file mode 100644 index 0000000..48142d4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDataSource.java @@ -0,0 +1,120 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +/** + * @Description: 多数据源管理 + * @Author: zita + * @Date: 2019-12-25 + * @Version: V1.0 + */ +@Data +@TableName("sys_data_source") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_data_source对象", description = "多数据源管理") +public class SysDataSource { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 数据源编码 + */ + @Excel(name = "数据源编码", width = 15) + @ApiModelProperty(value = "数据源编码") + private java.lang.String code; + /** + * 数据源名称 + */ + @Excel(name = "数据源名称", width = 15) + @ApiModelProperty(value = "数据源名称") + private java.lang.String name; + /** + * 描述 + */ + @Excel(name = "备注", width = 15) + @ApiModelProperty(value = "备注") + private java.lang.String remark; + /** + * 数据库类型 + */ + @Dict(dicCode = "database_type") + @Excel(name = "数据库类型", width = 15, dicCode = "database_type") + @ApiModelProperty(value = "数据库类型") + private java.lang.String dbType; + /** + * 驱动类 + */ + @Excel(name = "驱动类", width = 15) + @ApiModelProperty(value = "驱动类") + private java.lang.String dbDriver; + /** + * 数据源地址 + */ + @Excel(name = "数据源地址", width = 15) + @ApiModelProperty(value = "数据源地址") + private java.lang.String dbUrl; + /** + * 数据库名称 + */ + @Excel(name = "数据库名称", width = 15) + @ApiModelProperty(value = "数据库名称") + private java.lang.String dbName; + /** + * 用户名 + */ + @Excel(name = "用户名", width = 15) + @ApiModelProperty(value = "用户名") + private java.lang.String dbUsername; + /** + * 密码 + */ + @Excel(name = "密码", width = 15) + @ApiModelProperty(value = "密码") + private java.lang.String dbPassword; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建日期") + private java.util.Date createTime; + /** + * 更新人 + */ + @ApiModelProperty(value = "更新人") + private java.lang.String updateBy; + /** + * 更新日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新日期") + private java.util.Date updateTime; + /** + * 所属部门 + */ + @Excel(name = "所属部门", width = 15) + @ApiModelProperty(value = "所属部门") + private java.lang.String sysOrgCode; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepart.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepart.java new file mode 100644 index 0000000..5e764e5 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepart.java @@ -0,0 +1,193 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; +import java.util.Objects; + +/** + *

+ * 部门表 + *

+ * + * @Author Steve + * @Since 2019-01-22 + */ +@Data +@TableName("sys_depart") +public class SysDepart implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + /** + * 父机构ID + */ + private String parentId; + /** + * 机构/部门名称 + */ + @Excel(name = "机构/部门名称", width = 15) + private String departName; + /** + * 英文名 + */ + @Excel(name = "英文名", width = 15) + private String departNameEn; + /** + * 缩写 + */ + private String departNameAbbr; + /** + * 排序 + */ + @Excel(name = "排序", width = 15) + private Integer departOrder; + /** + * 描述 + */ + @Excel(name = "描述", width = 15) + private String description; + /** + * 机构类别 1=公司,2=组织机构,3=岗位 + */ + @Excel(name = "机构类别", width = 15, dicCode = "org_category") + private String orgCategory; + /** + * 机构类型 + */ + private String orgType; + /** + * 机构编码 + */ + @Excel(name = "机构编码", width = 15) + private String orgCode; + /** + * 手机号 + */ + @Excel(name = "手机号", width = 15) + private String mobile; + /** + * 传真 + */ + @Excel(name = "传真", width = 15) + private String fax; + /** + * 地址 + */ + @Excel(name = "地址", width = 15) + private String address; + /** + * 备注 + */ + @Excel(name = "备注", width = 15) + private String memo; + /** + * 状态(1启用,0不启用) + */ + @Dict(dicCode = "depart_status") + private String status; + /** + * 删除状态(0,正常,1已删除) + */ + @Dict(dicCode = "del_flag") + private String delFlag; + /** + * 对接企业微信的ID + */ + private String qywxIdentifier; + /** + * 创建人 + */ + private String createBy; + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + /** + * 更新人 + */ + private String updateBy; + /** + * 更新日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + //update-begin---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段负责人ids和旧的负责人ids + /** + * 部门负责人的ids + */ + @TableField(exist = false) + private String directorUserIds; + /** + * 旧的部门负责人的ids(用于比较删除和新增) + */ + @TableField(exist = false) + private String oldDirectorUserIds; + //update-end---author:wangshuai ---date:20200308 for:[JTC-119]新增字段负责人ids和旧的负责人ids + + /** + * 重写equals方法 + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + if (!super.equals(o)) { + return false; + } + SysDepart depart = (SysDepart) o; + return Objects.equals(id, depart.id) && + Objects.equals(parentId, depart.parentId) && + Objects.equals(departName, depart.departName) && + Objects.equals(departNameEn, depart.departNameEn) && + Objects.equals(departNameAbbr, depart.departNameAbbr) && + Objects.equals(departOrder, depart.departOrder) && + Objects.equals(description, depart.description) && + Objects.equals(orgCategory, depart.orgCategory) && + Objects.equals(orgType, depart.orgType) && + Objects.equals(orgCode, depart.orgCode) && + Objects.equals(mobile, depart.mobile) && + Objects.equals(fax, depart.fax) && + Objects.equals(address, depart.address) && + Objects.equals(memo, depart.memo) && + Objects.equals(status, depart.status) && + Objects.equals(delFlag, depart.delFlag) && + Objects.equals(createBy, depart.createBy) && + Objects.equals(createTime, depart.createTime) && + Objects.equals(updateBy, depart.updateBy) && + Objects.equals(updateTime, depart.updateTime); + } + + /** + * 重写hashCode方法 + */ + @Override + public int hashCode() { + + return Objects.hash(super.hashCode(), id, parentId, departName, + departNameEn, departNameAbbr, departOrder, description, orgCategory, + orgType, orgCode, mobile, fax, address, memo, status, + delFlag, createBy, createTime, updateBy, updateTime); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartPermission.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartPermission.java new file mode 100644 index 0000000..721b99b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartPermission.java @@ -0,0 +1,58 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; + +/** + * @Description: 部门权限表 + * @Author: zita + * @Date: 2020-02-11 + * @Version: V1.0 + */ +@Data +@TableName("sys_depart_permission") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_depart_permission对象", description = "部门权限表") +public class SysDepartPermission { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 部门id + */ + @Excel(name = "部门id", width = 15) + @ApiModelProperty(value = "部门id") + private java.lang.String departId; + /** + * 权限id + */ + @Excel(name = "权限id", width = 15) + @ApiModelProperty(value = "权限id") + private java.lang.String permissionId; + /** + * 数据规则id + */ + @ApiModelProperty(value = "数据规则id") + private java.lang.String dataRuleIds; + + public SysDepartPermission() { + + } + + public SysDepartPermission(String departId, String permissionId) { + this.departId = departId; + this.permissionId = permissionId; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRole.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRole.java new file mode 100644 index 0000000..b32f86f --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRole.java @@ -0,0 +1,90 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +/** + * @Description: 部门角色 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +@Data +@TableName("sys_depart_role") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_depart_role对象", description = "部门角色") +public class SysDepartRole { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 部门id + */ + @Excel(name = "部门id", width = 15) + @ApiModelProperty(value = "部门id") + @Dict(dictTable = "sys_depart", dicText = "depart_name", dicCode = "id") + private java.lang.String departId; + /** + * 部门角色名称 + */ + @Excel(name = "部门角色名称", width = 15) + @ApiModelProperty(value = "部门角色名称") + private java.lang.String roleName; + /** + * 部门角色编码 + */ + @Excel(name = "部门角色编码", width = 15) + @ApiModelProperty(value = "部门角色编码") + private java.lang.String roleCode; + /** + * 描述 + */ + @Excel(name = "描述", width = 15) + @ApiModelProperty(value = "描述") + private java.lang.String description; + /** + * 创建人 + */ + @Excel(name = "创建人", width = 15) + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /** + * 创建时间 + */ + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private java.util.Date createTime; + /** + * 更新人 + */ + @Excel(name = "更新人", width = 15) + @ApiModelProperty(value = "更新人") + private java.lang.String updateBy; + /** + * 更新时间 + */ + @Excel(name = "更新时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新时间") + private java.util.Date updateTime; + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRolePermission.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRolePermission.java new file mode 100644 index 0000000..12b12d6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRolePermission.java @@ -0,0 +1,78 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * @Description: 部门角色权限 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +@Data +@TableName("sys_depart_role_permission") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_depart_role_permission对象", description = "部门角色权限") +public class SysDepartRolePermission { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 部门id + */ + @Excel(name = "部门id", width = 15) + @ApiModelProperty(value = "部门id") + private java.lang.String departId; + /** + * 角色id + */ + @Excel(name = "角色id", width = 15) + @ApiModelProperty(value = "角色id") + private java.lang.String roleId; + /** + * 权限id + */ + @Excel(name = "权限id", width = 15) + @ApiModelProperty(value = "权限id") + private java.lang.String permissionId; + /** + * dataRuleIds + */ + @Excel(name = "dataRuleIds", width = 15) + @ApiModelProperty(value = "dataRuleIds") + private java.lang.String dataRuleIds; + /** + * 操作时间 + */ + @Excel(name = "操作时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "操作时间") + private java.util.Date operateDate; + /** + * 操作ip + */ + private java.lang.String operateIp; + + public SysDepartRolePermission() { + } + + public SysDepartRolePermission(String roleId, String permissionId) { + this.roleId = roleId; + this.permissionId = permissionId; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRoleUser.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRoleUser.java new file mode 100644 index 0000000..35b39fc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDepartRoleUser.java @@ -0,0 +1,53 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; + +/** + * @Description: 部门角色人员信息 + * @Author: zita + * @Date: 2020-02-13 + * @Version: V1.0 + */ +@Data +@TableName("sys_depart_role_user") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_depart_role_user对象", description = "部门角色人员信息") +public class SysDepartRoleUser { + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键id") + private java.lang.String id; + /** + * 用户id + */ + @Excel(name = "用户id", width = 15) + @ApiModelProperty(value = "用户id") + private java.lang.String userId; + /** + * 角色id + */ + @Excel(name = "角色id", width = 15) + @ApiModelProperty(value = "角色id") + private java.lang.String droleId; + + public SysDepartRoleUser() { + + } + + public SysDepartRoleUser(String userId, String droleId) { + this.userId = userId; + this.droleId = droleId; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDict.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDict.java new file mode 100644 index 0000000..ca592d8 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDict.java @@ -0,0 +1,84 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 字典表 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysDict implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * [预留字段,暂时无用] + * 字典类型,0 string,1 number类型,2 boolean + * 前端js对stirng类型和number类型 boolean 类型敏感,需要区分。在select 标签匹配的时候会用到 + * 默认为string类型 + */ + private Integer type; + + /** + * 字典名称 + */ + private String dictName; + + /** + * 字典编码 + */ + private String dictCode; + + /** + * 描述 + */ + private String description; + + /** + * 删除状态 + */ + @TableLogic + private Integer delFlag; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDictItem.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDictItem.java new file mode 100644 index 0000000..4f0c941 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysDictItem.java @@ -0,0 +1,80 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysDictItem implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 字典id + */ + private String dictId; + + /** + * 字典项文本 + */ + @Excel(name = "字典项文本", width = 20) + private String itemText; + + /** + * 字典项值 + */ + @Excel(name = "字典项值", width = 30) + private String itemValue; + + /** + * 描述 + */ + @Excel(name = "描述", width = 40) + private String description; + + /** + * 排序 + */ + @Excel(name = "排序", width = 15, type = 4) + private Integer sortOrder; + + + /** + * 状态(1启用 0不启用) + */ + @Dict(dicCode = "dict_item_status") + private Integer status; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysFillRule.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysFillRule.java new file mode 100644 index 0000000..0ff50cd --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysFillRule.java @@ -0,0 +1,86 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * @Description: 填值规则 + * @Author: zita + * @Date: 2019-11-07 + * @Version: V1.0 + */ +@Data +@TableName("sys_fill_rule") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_fill_rule对象", description = "填值规则") +public class SysFillRule { + + /** + * 主键ID + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键ID") + private java.lang.String id; + /** + * 规则名称 + */ + @Excel(name = "规则名称", width = 15) + @ApiModelProperty(value = "规则名称") + private java.lang.String ruleName; + /** + * 规则Code + */ + @Excel(name = "规则Code", width = 15) + @ApiModelProperty(value = "规则Code") + private java.lang.String ruleCode; + /** + * 规则实现类 + */ + @Excel(name = "规则实现类", width = 15) + @ApiModelProperty(value = "规则实现类") + private java.lang.String ruleClass; + /** + * 规则参数 + */ + @Excel(name = "规则参数", width = 15) + @ApiModelProperty(value = "规则参数") + private java.lang.String ruleParams; + /** + * 修改人 + */ + @Excel(name = "修改人", width = 15) + @ApiModelProperty(value = "修改人") + private java.lang.String updateBy; + /** + * 修改时间 + */ + @Excel(name = "修改时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "修改时间") + private java.util.Date updateTime; + /** + * 创建人 + */ + @Excel(name = "创建人", width = 15) + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /** + * 创建时间 + */ + @Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private java.util.Date createTime; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysGatewayRoute.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysGatewayRoute.java new file mode 100644 index 0000000..bcd65cf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysGatewayRoute.java @@ -0,0 +1,133 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + +/** + * @Description: gateway路由管理 + * @Author: zita + * @Date: 2020-05-26 + * @Version: V1.0 + */ +@Data +@TableName("sys_gateway_route") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_gateway_route对象", description = "gateway路由管理") +public class SysGatewayRoute implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + /** + * routerKEy + */ + @ApiModelProperty(value = "路由ID") + private String routerId; + + /** + * 服务名 + */ + @Excel(name = "服务名", width = 15) + @ApiModelProperty(value = "服务名") + private String name; + + /** + * 服务地址 + */ + @Excel(name = "服务地址", width = 15) + @ApiModelProperty(value = "服务地址") + private String uri; + + /** + * 断言配置 + */ + private String predicates; + + /** + * 过滤配置 + */ + private String filters; + + /** + * 是否忽略前缀0-否 1-是 + */ + @Excel(name = "忽略前缀", width = 15) + @ApiModelProperty(value = "忽略前缀") + @Dict(dicCode = "yn") + private Integer stripPrefix; + + /** + * 是否重试0-否 1-是 + */ + @Excel(name = "是否重试", width = 15) + @ApiModelProperty(value = "是否重试") + @Dict(dicCode = "yn") + private Integer retryable; + + /** + * 是否为保留数据:0-否 1-是 + */ + @Excel(name = "保留数据", width = 15) + @ApiModelProperty(value = "保留数据") + @Dict(dicCode = "yn") + private Integer persistable; + + /** + * 是否在接口文档中展示:0-否 1-是 + */ + @Excel(name = "在接口文档中展示", width = 15) + @ApiModelProperty(value = "在接口文档中展示") + @Dict(dicCode = "yn") + private Integer showApi; + + /** + * 状态 1有效 0无效 + */ + @Excel(name = "状态", width = 15) + @ApiModelProperty(value = "状态") + @Dict(dicCode = "yn") + private Integer status; + + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private String createBy; + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建日期") + private Date createTime; + /* *//**更新人*//* + @ApiModelProperty(value = "更新人") + private String updateBy; + *//**更新日期*//* + @JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新日期") + private Date updateTime; + *//**所属部门*//* + @ApiModelProperty(value = "所属部门") + private String sysOrgCode;*/ +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysLog.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysLog.java new file mode 100644 index 0000000..6999afe --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysLog.java @@ -0,0 +1,113 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 系统日志表 + *

+ * + * @Author zhangweijian + * @since 2018-12-26 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysLog implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 耗时 + */ + private Long costTime; + + /** + * IP + */ + private String ip; + + /** + * 请求参数 + */ + private String requestParam; + + /** + * 请求类型 + */ + @Dict(dicCode = "log_type") + private String requestType; + + /** + * 请求路径 + */ + private String requestUrl; + /** + * 请求方法 + */ + private String method; + + /** + * 操作人用户名称 + */ + private String username; + /** + * 操作人用户账户 + */ + private String userId; + /** + * 操作详细日志 + */ + private String logContent; + + /** + * 日志类型(1登录日志,2操作日志) + */ + @Dict(dicCode = "log_type") + private Integer logType; + + /** + * 操作类型(1查询,2添加,3修改,4删除,5导入,6导出) + */ + @Dict(dicCode = "operate_type") + private Integer operateType; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermission.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermission.java new file mode 100644 index 0000000..9382c5c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermission.java @@ -0,0 +1,200 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + + +/** + *

+ * 菜单权限表 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysPermission implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 父id + */ + private String parentId; + + @ApiModelProperty(value = "中文") + private String name; + + @ApiModelProperty(value = "繁体") + private String traditionalName; + + @ApiModelProperty(value = "英文") + private String englishName; + + /** + * 菜单权限编码,例如:“sys:schedule:list,sys:schedule:info”,多个逗号隔开 + */ + private String perms; + /** + * 权限策略1显示2禁用 + */ + private String permsType; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 组件 + */ + private String component; + + /** + * 组件名字 + */ + private String componentName; + + /** + * 路径 + */ + private String url; + /** + * 一级菜单跳转地址 + */ + private String redirect; + + /** + * 菜单排序 + */ + private Double sortNo; + + /** + * 类型(0:一级菜单;1:子菜单 ;2:按钮权限) + */ + @Dict(dicCode = "menu_type") + private Integer menuType; + + /** + * 是否叶子节点: 1:是 0:不是 + */ + @TableField(value = "is_leaf") + private boolean leaf; + + /** + * 是否路由菜单: 0:不是 1:是(默认值1) + */ + @TableField(value = "is_route") + private boolean route; + + + /** + * 是否缓存页面: 0:不是 1:是(默认值1) + */ + @TableField(value = "keep_alive") + private boolean keepAlive; + + /** + * 描述 + */ + private String description; + + /** + * 创建人 + */ + private String createBy; + + /** + * 删除状态 0正常 1已删除 + */ + private Integer delFlag; + + /** + * 是否配置菜单的数据权限 1是0否 默认0 + */ + private Integer ruleFlag; + + /** + * 是否隐藏路由菜单: 0否,1是(默认值0) + */ + private boolean hidden; + + /** + * 是否隐藏Tab: 0否,1是(默认值0) + */ + private boolean hideTab; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 按钮权限状态(0无效1有效) + */ + private java.lang.String status; + + /** + * alwaysShow + */ + private boolean alwaysShow; + + /*update_begin author:wuxianquan date:20190908 for:实体增加字段 */ + /** + * 外链菜单打开方式 0/内部打开 1/外部打开 + */ + private boolean internalOrExternal; + /*update_end author:wuxianquan date:20190908 for:实体增加字段 */ + + public SysPermission() { + + } + + public SysPermission(boolean index) { + if (index) { + this.id = "9502685863ab87f0ad1134142788a385"; + this.name = "首页"; + this.component = "dashboard/Analysis"; + this.componentName = "dashboard-analysis"; + this.url = "/dashboard/analysis"; + this.icon = "home"; + this.menuType = 0; + this.sortNo = 0.0; + this.ruleFlag = 0; + this.delFlag = 0; + this.alwaysShow = false; + this.route = true; + this.keepAlive = true; + this.leaf = true; + this.hidden = false; + } + + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermissionDataRule.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermissionDataRule.java new file mode 100644 index 0000000..45fc0c4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPermissionDataRule.java @@ -0,0 +1,82 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 菜单权限规则表 + *

+ * + * @Author huangzhilin + * @since 2019-03-29 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysPermissionDataRule implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 对应的菜单id + */ + private String permissionId; + + /** + * 规则名称 + */ + private String ruleName; + + /** + * 字段 + */ + private String ruleColumn; + + /** + * 条件 + */ + private String ruleConditions; + + /** + * 规则值 + */ + private String ruleValue; + + /** + * 状态值 1有效 0无效 + */ + private String status; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 创建人 + */ + private String createBy; + + /** + * 修改时间 + */ + private Date updateTime; + + /** + * 修改人 + */ + private String updateBy; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPosition.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPosition.java new file mode 100644 index 0000000..55373a9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysPosition.java @@ -0,0 +1,88 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +/** + * @Description: 职务表 + * @Author: zita + * @Date: 2019-09-19 + * @Version: V1.0 + */ +@Data +@TableName("sys_position") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_position对象", description = "职务表") +public class SysPosition { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 职务编码 + */ + @Excel(name = "职务编码", width = 15) + @ApiModelProperty(value = "职务编码") + private java.lang.String code; + /** + * 职务名称 + */ + @Excel(name = "职务名称", width = 15) + @ApiModelProperty(value = "职务名称") + private java.lang.String name; + /** + * 职级 + */ + @Excel(name = "职级", width = 15, dicCode = "position_rank") + @ApiModelProperty(value = "职级") + @Dict(dicCode = "position_rank") + private java.lang.String postRank; + /** + * 公司id + */ + @ApiModelProperty(value = "公司id") + private java.lang.String companyId; + /** + * 创建人 + */ + @ApiModelProperty(value = "创建人") + private java.lang.String createBy; + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建时间") + private java.util.Date createTime; + /** + * 修改人 + */ + @ApiModelProperty(value = "修改人") + private java.lang.String updateBy; + /** + * 修改时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "修改时间") + private java.util.Date updateTime; + /** + * 组织机构编码 + */ + @ApiModelProperty(value = "组织机构编码") + private java.lang.String sysOrgCode; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRole.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRole.java new file mode 100644 index 0000000..15cc621 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRole.java @@ -0,0 +1,79 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 角色表 + *

+ * + * @Author scott + * @since 2018-12-19 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysRole implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 角色名称 + */ + @Excel(name = "角色名", width = 15) + private String roleName; + + /** + * 角色编码 + */ + @Excel(name = "角色编码", width = 15) + private String roleCode; + + /** + * 描述 + */ + @Excel(name = "描述", width = 60) + private String description; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRoleIndex.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRoleIndex.java new file mode 100644 index 0000000..bf9de91 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRoleIndex.java @@ -0,0 +1,92 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * @Description: 角色首页配置 + * @Author: liusq + * @Date: 2022-03-25 + * @Version: V1.0 + */ +@Data +@TableName("sys_role_index") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_role_index对象", description = "角色首页配置") +public class SysRoleIndex { + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "id") + private java.lang.String id; + /** + * 角色编码 + */ + @Excel(name = "角色编码", width = 15) + @ApiModelProperty(value = "角色编码") + private java.lang.String roleCode; + /** + * 路由地址 + */ + @Excel(name = "路由地址", width = 15) + @ApiModelProperty(value = "路由地址") + private java.lang.String url; + /** + * 优先级 + */ + @Excel(name = "优先级", width = 15) + @ApiModelProperty(value = "优先级") + private Integer priority; + /** + * 路由地址 + */ + @Excel(name = "状态", width = 15) + @ApiModelProperty(value = "状态") + private java.lang.String status; + /** + * 创建人登录名称 + */ + @Excel(name = "创建人登录名称", width = 15) + @ApiModelProperty(value = "创建人登录名称") + private java.lang.String createBy; + /** + * 创建日期 + */ + @Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建日期") + private java.util.Date createTime; + /** + * 更新人登录名称 + */ + @Excel(name = "更新人登录名称", width = 15) + @ApiModelProperty(value = "更新人登录名称") + private java.lang.String updateBy; + /** + * 更新日期 + */ + @Excel(name = "更新日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新日期") + private java.util.Date updateTime; + /** + * 所属部门 + */ + @Excel(name = "所属部门", width = 15) + @ApiModelProperty(value = "所属部门") + private java.lang.String sysOrgCode; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRolePermission.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRolePermission.java new file mode 100644 index 0000000..7e0173f --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysRolePermission.java @@ -0,0 +1,70 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 角色权限表 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysRolePermission implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 角色id + */ + private String roleId; + + /** + * 权限id + */ + private String permissionId; + + /** + * 数据权限 + */ + private String dataRuleIds; + + /** + * 操作时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date operateDate; + + /** + * 操作ip + */ + private String operateIp; + + public SysRolePermission() { + } + + public SysRolePermission(String roleId, String permissionId) { + this.roleId = roleId; + this.permissionId = permissionId; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysTenant.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysTenant.java new file mode 100644 index 0000000..15d2790 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysTenant.java @@ -0,0 +1,66 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.io.Serializable; +import java.util.Date; + +/** + * 租户信息 + * + * @author: smcp + */ +@Data +@TableName("sys_tenant") +public class SysTenant implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 编码 + */ + private Integer id; + + /** + * 名称 + */ + private String name; + + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + /** + * 开始时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date beginDate; + + /** + * 结束时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date endDate; + + /** + * 状态 1正常 0冻结 + */ + @Dict(dicCode = "tenant_status") + private Integer status; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysThirdAccount.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysThirdAccount.java new file mode 100644 index 0000000..66134be --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysThirdAccount.java @@ -0,0 +1,106 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +/** + * @Description: 第三方登录账号表 + * @Author: zita + * @Date: 2020-11-17 + * @Version: V1.0 + */ +@Data +@TableName("sys_third_account") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +@ApiModel(value = "sys_third_account对象", description = "第三方登录账号表") +public class SysThirdAccount { + + /** + * 编号 + */ + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "编号") + private java.lang.String id; + /** + * 第三方登录id + */ + @Excel(name = "第三方登录id", width = 15) + @ApiModelProperty(value = "第三方登录id") + private java.lang.String sysUserId; + /** + * 登录来源 + */ + @Excel(name = "登录来源", width = 15) + @ApiModelProperty(value = "登录来源") + private java.lang.String thirdType; + /** + * 头像 + */ + @Excel(name = "头像", width = 15) + @ApiModelProperty(value = "头像") + private java.lang.String avatar; + /** + * 状态(1-正常,2-冻结) + */ + @Excel(name = "状态(1-正常,2-冻结)", width = 15) + @ApiModelProperty(value = "状态(1-正常,2-冻结)") + private Integer status; + /** + * 删除状态(0-正常,1-已删除) + */ + @Excel(name = "删除状态(0-正常,1-已删除)", width = 15) + @ApiModelProperty(value = "删除状态(0-正常,1-已删除)") + private Integer delFlag; + /** + * 真实姓名 + */ + @Excel(name = "真实姓名", width = 15) + @ApiModelProperty(value = "真实姓名") + private java.lang.String realname; + /** + * 真实姓名 + */ + @Excel(name = "真实姓名", width = 15) + @ApiModelProperty(value = "真实姓名") + private java.lang.String thirdUserUuid; + /** + * 真实姓名 + */ + @Excel(name = "第三方用户账号", width = 15) + @ApiModelProperty(value = "第三方用户账号") + private java.lang.String thirdUserId; + /** + * 创建人 + */ + @Excel(name = "创建人", width = 15) + private java.lang.String createBy; + /** + * 创建日期 + */ + @Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + /** + * 修改人 + */ + @Excel(name = "修改人", width = 15) + private java.lang.String updateBy; + /** + * 修改日期 + */ + @Excel(name = "修改日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUser.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUser.java new file mode 100644 index 0000000..c1d2913 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUser.java @@ -0,0 +1,116 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.fasterxml.jackson.annotation.JsonProperty; +import digital.base.annotation.Dict; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +@TableName("sys_user") +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysUser implements Serializable { + + private static final long serialVersionUID = 1L; + + @ApiModelProperty(value = "主键") + @TableId(type = IdType.AUTO) + private Integer id; + + @ApiModelProperty(value = "appKey") + private String appKey; + + @ApiModelProperty(value = "appSecret") + private String appSecret; + + @ApiModelProperty(value = "姓名") + private String username; + + @ApiModelProperty(value = "公司名称") + private String companyName; + + @ApiModelProperty(value = "数字人定做次数 制作成功+1") + private Integer digitalPersonCustomTotal; + + @ApiModelProperty(value = "可以同时开播的直播间数量") + private Integer liveNum; + + @ApiModelProperty(value = "成功 制作的视频时长") + private BigDecimal videoDuration; + + @ApiModelProperty(value = "视频制作成功个数") + private Integer videoNumSuc; + + @ApiModelProperty(value = "视频制作失败个数") + private Integer videoNumFail; + + @ApiModelProperty(value = "真实姓名") + private String realname; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String password; + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private String salt; + + @ApiModelProperty(value = "头像") + private String avatar; + + @ApiModelProperty(value = "生日") + @Excel(name = "生日", width = 15, format = "yyyy-MM-dd") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + @ApiModelProperty(value = "性别") + @Dict(dicCode = "sex") + private Integer sex; + + @ApiModelProperty(value = "电子邮件") + private String email; + + @ApiModelProperty(value = "电话") + private String phone; + + @ApiModelProperty(value = "状态(1:正常 2:冻结 )") + @Excel(name = "状态", width = 15, dicCode = "user_status") + @Dict(dicCode = "user_status") + private Integer status; + + @TableLogic + private Integer delFlag; + +// @ApiModelProperty(value = "座机号") +// private String telephone; + + @ApiModelProperty(value = "创建人") + private String createBy; + + @ApiModelProperty(value = "创建时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + @ApiModelProperty(value = "更新") + private String updateBy; + + @ApiModelProperty(value = "更新时间") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date updateTime; + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserAgent.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserAgent.java new file mode 100644 index 0000000..dee7d2a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserAgent.java @@ -0,0 +1,102 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: 用户代理人设置 + * @Author: zita + * @Date: 2019-04-17 + * @Version: V1.0 + */ +@Data +@TableName("sys_user_agent") +public class SysUserAgent implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 序号 + */ + @TableId(type = IdType.ASSIGN_ID) + private java.lang.String id; + /** + * 用户名 + */ + @Excel(name = "用户名", width = 15) + private java.lang.String userName; + /** + * 代理人用户名 + */ + @Excel(name = "代理人用户名", width = 15) + private java.lang.String agentUserName; + /** + * 代理开始时间 + */ + @Excel(name = "代理开始时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date startTime; + /** + * 代理结束时间 + */ + @Excel(name = "代理结束时间", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date endTime; + /** + * 状态0无效1有效 + */ + @Excel(name = "状态0无效1有效", width = 15) + private java.lang.String status; + /** + * 创建人名称 + */ + @Excel(name = "创建人名称", width = 15) + private java.lang.String createName; + /** + * 创建人登录名称 + */ + @Excel(name = "创建人登录名称", width = 15) + private java.lang.String createBy; + /** + * 创建日期 + */ + @Excel(name = "创建日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date createTime; + /** + * 更新人名称 + */ + @Excel(name = "更新人名称", width = 15) + private java.lang.String updateName; + /** + * 更新人登录名称 + */ + @Excel(name = "更新人登录名称", width = 15) + private java.lang.String updateBy; + /** + * 更新日期 + */ + @Excel(name = "更新日期", width = 20, format = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date updateTime; + /** + * 所属部门 + */ + @Excel(name = "所属部门", width = 15) + private java.lang.String sysOrgCode; + /** + * 所属公司 + */ + @Excel(name = "所属公司", width = 15) + private java.lang.String sysCompanyCode; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserDepart.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserDepart.java new file mode 100644 index 0000000..05e4ddc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserDepart.java @@ -0,0 +1,44 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Description: 用户部门 + * @author: smcp + */ +@Data +@TableName("sys_user_depart") +public class SysUserDepart implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 主键id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + /** + * 用户id + */ + private String userId; + /** + * 部门id + */ + private String depId; + + public SysUserDepart(String id, String userId, String depId) { + super(); + this.id = id; + this.userId = userId; + this.depId = depId; + } + + public SysUserDepart(String id, String departId) { + this.userId = id; + this.depId = departId; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserRole.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserRole.java new file mode 100644 index 0000000..370a985 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysUserRole.java @@ -0,0 +1,48 @@ +package digital.system.jeecg.system.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +import java.io.Serializable; + +/** + *

+ * 用户角色表 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysUserRole implements Serializable { + + private static final long serialVersionUID = 1L; + + @TableId(type = IdType.ASSIGN_ID) + private String id; + + /** + * 用户id + */ + private String userId; + + /** + * 角色id + */ + private String roleId; + + public SysUserRole() { + } + + public SysUserRole(String userId, String roleId) { + this.userId = userId; + this.roleId = roleId; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/entity/SysVersion.java b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysVersion.java new file mode 100644 index 0000000..d8a12b7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/entity/SysVersion.java @@ -0,0 +1,80 @@ +package digital.system.jeecg.system.entity; + +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.Date; +import java.math.BigDecimal; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; +import org.jeecgframework.poi.excel.annotation.Excel; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * @Description: sys_version + * @Author: jeecg-boot + * @Date: 2024-03-07 + * @Version: V1.0 + */ +@Data +@TableName("sys_version") +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = false) +@ApiModel(value = "sys_version对象", description = "sys_version") +public class SysVersion implements Serializable { + private static final long serialVersionUID = 1L; + + + @TableId(type = IdType.ASSIGN_ID) + @ApiModelProperty(value = "主键") + private String id; + + @Excel(name = "版本类型 1 是本地 2 是第三方", width = 15) + @ApiModelProperty(value = "版本类型 1 是本地 2 是第三方") + private String releaseVersion; + /** + * 备注 + */ + @Excel(name = "备注", width = 15) + @ApiModelProperty(value = "备注") + private String remark; + /** + * 创建人登录名称 + */ + @ApiModelProperty(value = "创建人登录名称") + private String createBy; + /** + * 创建日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "创建日期") + private Date createTime; + /** + * 更新人登录名称 + */ + @ApiModelProperty(value = "更新人登录名称") + private String updateBy; + /** + * 更新日期 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @ApiModelProperty(value = "更新日期") + private Date updateTime; + /** + * 删除状态(0-正常,1-已删除) + */ + @Excel(name = "删除状态(0-正常,1-已删除)", width = 15) + @ApiModelProperty(value = "删除状态(0-正常,1-已删除)") + @TableLogic + private Integer delFlag; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/DpUserMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/DpUserMapper.java new file mode 100644 index 0000000..edff3bc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/DpUserMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.bean.task.DpUser; + +/** + * @Description: dp_user + * @Author: jeecg-boot + * @Date: 2024-04-17 + * @Version: V1.0 + */ +public interface DpUserMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementMapper.java new file mode 100644 index 0000000..7d71210 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementMapper.java @@ -0,0 +1,28 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.system.entity.SysAnnouncement; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 系统通告表 + * @Author: zita + * @Date: 2019-01-02 + * @Version: V1.0 + */ +public interface SysAnnouncementMapper extends BaseMapper { + + /** + * 通过消息类型和用户id获取系统通告 + * + * @param page + * @param userId 用户id + * @param msgCategory 消息类型 + * @return + */ + List querySysCementListByUserId(Page page, @Param("userId") String userId, @Param("msgCategory") String msgCategory); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementSendMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementSendMapper.java new file mode 100644 index 0000000..8378beb --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysAnnouncementSendMapper.java @@ -0,0 +1,36 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.system.entity.SysAnnouncementSend; +import digital.system.jeecg.system.model.AnnouncementSendModel; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 用户通告阅读标记表 + * @Author: zita + * @Date: 2019-02-21 + * @Version: V1.0 + */ +public interface SysAnnouncementSendMapper extends BaseMapper { + + /** + * 通过用户id查询 用户通告阅读标记表 + * + * @param userId 用户id + * @return + */ + public List queryByUserId(@Param("userId") String userId); + + /** + * 获取我的消息 + * + * @param announcementSendModel + * @param page + * @return + */ + public List getMyAnnouncementSendList(Page page, @Param("announcementSendModel") AnnouncementSendModel announcementSendModel); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCategoryMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCategoryMapper.java new file mode 100644 index 0000000..5aacda1 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCategoryMapper.java @@ -0,0 +1,39 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.model.TreeSelectModel; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import digital.system.jeecg.system.entity.SysCategory; + +import java.util.List; +import java.util.Map; + +/** + * @Description: 分类字典 + * @Author: zita + * @Date: 2019-05-29 + * @Version: V1.0 + */ +public interface SysCategoryMapper extends BaseMapper { + + /** + * 根据父级ID查询树节点数据 + * + * @param pid + * @param query + * @return + */ + public List queryListByPid(@Param("pid") String pid, @Param("query") Map query); + + /** + * 通过code查询分类字典表 + * + * @param code + * @return + */ + @Select("SELECT ID FROM sys_category WHERE CODE = #{code,jdbcType=VARCHAR}") + public String queryIdByCode(@Param("code") String code); + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCheckRuleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCheckRuleMapper.java new file mode 100644 index 0000000..2293b7c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysCheckRuleMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysCheckRule; + +/** + * @Description: 编码校验规则 + * @Author: zita + * @Date: 2020-02-04 + * @Version: V1.0 + */ +public interface SysCheckRuleMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataLogMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataLogMapper.java new file mode 100644 index 0000000..fa93555 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataLogMapper.java @@ -0,0 +1,21 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; +import digital.system.jeecg.system.entity.SysDataLog; + +/** + * @Description: 系统数据日志Mapper接口 + * @author: smcp + */ +public interface SysDataLogMapper extends BaseMapper { + /** + * 通过表名及数据Id获取最大版本 + * + * @param tableName + * @param dataId + * @return + */ + public String queryMaxDataVer(@Param("tableName") String tableName, @Param("dataId") String dataId); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataSourceMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataSourceMapper.java new file mode 100644 index 0000000..b9cc72d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDataSourceMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDataSource; + +/** + * @Description: 多数据源管理 + * @Author: zita + * @Date: 2019-12-25 + * @Version: V1.0 + */ +public interface SysDataSourceMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartMapper.java new file mode 100644 index 0000000..a948b15 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartMapper.java @@ -0,0 +1,103 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDepart; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * 部门 Mapper 接口 + *

+ * + * @Author: Steve + * @Since: 2019-01-22 + */ +public interface SysDepartMapper extends BaseMapper { + + /** + * 根据用户ID查询部门集合 + * + * @param userId 用户id + * @return List + */ + public List queryUserDeparts(@Param("userId") String userId); + + /** + * 根据用户名查询部门 + * + * @param username + * @return + */ + public List queryDepartsByUsername(@Param("username") String username); + + /** + * 通过部门编码获取部门id + * + * @param orgCode 部门编码 + * @return String + */ + @Select("select id from sys_depart where org_code=#{orgCode}") + public String queryDepartIdByOrgCode(@Param("orgCode") String orgCode); + + /** + * 通过部门id 查询部门id,父id + * + * @param departId 部门id + * @return + */ + @Select("select id,parent_id from sys_depart where id=#{departId}") + public SysDepart getParentDepartId(@Param("departId") String departId); + + /** + * 根据部门Id查询,当前和下级所有部门IDS + * + * @param departId + * @return + */ + List getSubDepIdsByDepId(@Param("departId") String departId); + + /** + * 根据部门编码获取部门下所有IDS + * + * @param orgCodes + * @return + */ + List getSubDepIdsByOrgCodes(@org.apache.ibatis.annotations.Param("orgCodes") String[] orgCodes); + + /** + * 根据parent_id查询下级部门 + * + * @param parentId 父id + * @return List + */ + List queryTreeListByPid(@Param("parentId") String parentId); + + /** + * 根据id下级部门数量 + * + * @param parentId + * @return + */ + @Select("SELECT count(*) FROM sys_depart where del_flag ='0' AND parent_id = #{parentId,jdbcType=VARCHAR}") + Integer queryCountByPid(@Param("parentId") String parentId); + + /** + * 根据OrgCod查询所属公司信息 + * + * @param orgCode + * @return + */ + SysDepart queryCompByOrgCode(@Param("orgCode") String orgCode); + + /** + * 根据id下级部门 + * + * @param parentId + * @return + */ + @Select("SELECT * FROM sys_depart where del_flag ='0' AND parent_id = #{parentId,jdbcType=VARCHAR}") + List queryDeptByPid(@Param("parentId") String parentId); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartPermissionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartPermissionMapper.java new file mode 100644 index 0000000..eaf2662 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartPermissionMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDepartPermission; + +/** + * @Description: 部门权限表 + * @Author: zita + * @Date: 2020-02-11 + * @Version: V1.0 + */ +public interface SysDepartPermissionMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleMapper.java new file mode 100644 index 0000000..9a4c245 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleMapper.java @@ -0,0 +1,24 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDepartRole; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 部门角色 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +public interface SysDepartRoleMapper extends BaseMapper { + /** + * 根据用户id,部门id查询可授权所有部门角色 + * + * @param orgCode + * @param userId + * @return + */ + public List queryDeptRoleByDeptAndUser(@Param("orgCode") String orgCode, @Param("userId") String userId); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRolePermissionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRolePermissionMapper.java new file mode 100644 index 0000000..87a9cae --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRolePermissionMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDepartRolePermission; + +/** + * @Description: 部门角色权限 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +public interface SysDepartRolePermissionMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleUserMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleUserMapper.java new file mode 100644 index 0000000..7b7f154 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDepartRoleUserMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDepartRoleUser; + +/** + * @Description: 部门角色人员信息 + * @Author: zita + * @Date: 2020-02-13 + * @Version: V1.0 + */ +public interface SysDepartRoleUserMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictItemMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictItemMapper.java new file mode 100644 index 0000000..41a55d7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictItemMapper.java @@ -0,0 +1,34 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysDictItem; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * Mapper 接口 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +public interface SysDictItemMapper extends BaseMapper { + + /** + * 通过字典id查询字典项 + * + * @param mainId 字典id + * @return + */ + @Select("SELECT * FROM sys_dict_item WHERE DICT_ID = #{mainId} order by sort_order asc, item_value asc") + public List selectItemsByMainId(String mainId); + + /** + * 通过 字典项 item_value dict_code 查询字典项某一个参数 + */ + public String selectCodeByItemId(@Param("dictCode") String dictCode ,@Param("itemValue") String itemValue ); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictMapper.java new file mode 100644 index 0000000..3a0f240 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysDictMapper.java @@ -0,0 +1,300 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.system.entity.SysDict; +import digital.system.jeecg.system.entity.SysDictItem; +import digital.system.jeecg.system.model.DuplicateCheckVo; +import digital.system.jeecg.system.model.TreeSelectModel; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; +import digital.bean.jeecg.vo.DictModel; +import digital.bean.jeecg.vo.DictModelMany; +import digital.bean.jeecg.vo.DictQuery; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 字典表 Mapper 接口 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +public interface SysDictMapper extends BaseMapper { + + /** + * 重复检查SQL + * + * @param duplicateCheckVo + * @return + */ + @Deprecated + public Long duplicateCheckCountSql(DuplicateCheckVo duplicateCheckVo); + + /** + * 重复校验 sql语句 + * + * @param duplicateCheckVo + * @return + */ + @Deprecated + public Long duplicateCheckCountSqlNoDataId(DuplicateCheckVo duplicateCheckVo); + + /** + * 通过字典code获取字典数据 + * + * @param code 字典code + * @return List + */ + public List queryDictItemsByCode(@Param("code") String code); + + /** + * 通过字典code获取字典数据项 + * + * @param code 字典code + * @return List + */ + public List queryDictItems(@Param("code") String code); + + /** + * 查询有效的数据字典项 + * + * @param code + * @return + */ + List queryEnableDictItemsByCode(@Param("code") String code); + + + /** + * 通过多个字典code获取字典数据 + * + * @param dictCodeList + * @return + */ + public List queryDictItemsByCodeList(@Param("dictCodeList") List dictCodeList); + + /** + * 通过查询指定table的 text code 获取字典 + * + * @param table + * @param text + * @param code + * @return List + */ + @Deprecated + public List queryTableDictItemsByCode(@Param("table") String table, @Param("text") String text, @Param("code") String code); + + /** + * 通过查询指定table的 text code 获取字典(指定查询条件) + * + * @param table + * @param text + * @param code + * @param filterSql + * @return List + */ + @Deprecated + public List queryTableDictItemsByCodeAndFilter(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql); + + /** + * 通过查询指定table的 text code 获取字典 + * + * @param table + * @param key + * @param value + * @return List> + */ + @Deprecated + @Select("select ${key} as \"label\",${value} as \"value\" from ${table}") + public List> getDictByTableNgAlain(@Param("table") String table, @Param("key") String key, @Param("value") String value); + + /** + * 通过字典code获取字典数据 + * + * @param code + * @param key + * @return + */ + public String queryDictTextByKey(@Param("code") String code, @Param("key") String key); + + /** + * 可通过多个字典code查询翻译文本 + * + * @param dictCodeList 多个字典code + * @param keys 数据列表 + * @return + */ + List queryManyDictByKeys(@Param("dictCodeList") List dictCodeList, @Param("keys") List keys); + + /** + * 通过查询指定table的 text code key 获取字典值 + * + * @param table + * @param text + * @param code + * @param key + * @return String + */ + @Deprecated + public String queryTableDictTextByKey(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("key") String key); + + /** + * 通过查询指定table的 text code key 获取字典值,可批量查询 + * + * @param table + * @param text + * @param code + * @param keys + * @return + */ + @Deprecated + List queryTableDictTextByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keys") List keys); + + /** + * 通过查询指定table的 text code key 获取字典值,包含value + * + * @param table + * @param text + * @param code + * @param keyArray + * @return List + */ + @Deprecated + public List queryTableDictByKeys(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyArray") String[] keyArray); + + /** + * 查询所有部门 作为字典信息 id -->value,departName -->text + * + * @return + */ + public List queryAllDepartBackDictModel(); + + /** + * 查询所有用户 作为字典信息 username -->value,realname -->text + * + * @return + */ + public List queryAllUserBackDictModel(); + + /** + * 通过关键字查询出字典表 + * + * @param table + * @param text + * @param code + * @param keyword + * @return + */ + @Deprecated + public List queryTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword); + + + /** + * 通过关键字查询出字典表 + * + * @param page + * @param table + * @param text + * @param code + * @param keyword + * @return + */ + IPage queryTableDictItems(Page page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("keyword") String keyword); + + /** + * 根据表名、显示字段名、存储字段名 查询树 + * + * @param table + * @param text + * @param code + * @param pid + * @param hasChildField + * @param query + * @param pidField + * @return + */ + @Deprecated + List queryTreeList(@Param("query") Map query, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("pidField") String pidField, @Param("pid") String pid, @Param("hasChildField") String hasChildField); + + /** + * 删除 + * + * @param id + */ + @Select("delete from sys_dict where id = #{id}") + public void deleteOneById(@Param("id") String id); + + /** + * 查询被逻辑删除的数据 + * + * @return + */ + @Select("select * from sys_dict where del_flag = 1") + public List queryDeleteList(); + + /** + * 修改状态值 + * + * @param delFlag + * @param id + */ + @Update("update sys_dict set del_flag = #{flag,jdbcType=INTEGER} where id = #{id,jdbcType=VARCHAR}") + public void updateDictDelFlag(@Param("flag") int delFlag, @Param("id") String id); + + + /** + * 分页查询字典表数据 + * + * @param page + * @param query + * @return + */ + @Deprecated + public Page queryDictTablePageList(Page page, @Param("query") DictQuery query); + + + /** + * 查询 字典表数据 支持查询条件 分页 + * + * @param page + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @Deprecated + IPage queryTableDictWithFilter(Page page, @Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql); + + /** + * 查询 字典表数据 支持查询条件 查询所有 + * + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @Deprecated + List queryAllTableDictItems(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql); + + /** + * 查询字典表的数据 + * + * @param table 表名 + * @param text 显示字段名 + * @param code 存储字段名 + * @param filterSql 条件sql + * @param codeValues 存储字段值 作为查询条件in + * @return + */ + List queryTableDictByKeysAndFilterSql(@Param("table") String table, @Param("text") String text, @Param("code") String code, @Param("filterSql") String filterSql, @Param("codeValues") List codeValues); + + + List queryAreaItemsByCode(@Param("dictCode") String dictCode,@Param("areaIdList") List areaIdList); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysFillRuleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysFillRuleMapper.java new file mode 100644 index 0000000..a4a14cf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysFillRuleMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysFillRule; + +/** + * @Description: 填值规则 + * @Author: zita + * @Date: 2019-11-07 + * @Version: V1.0 + */ +public interface SysFillRuleMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysGatewayRouteMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysGatewayRouteMapper.java new file mode 100644 index 0000000..8be5d47 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysGatewayRouteMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysGatewayRoute; + +/** + * @Description: gateway路由管理 + * @Author: zita + * @Date: 2020-05-26 + * @Version: V1.0 + */ +public interface SysGatewayRouteMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysLogMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysLogMapper.java new file mode 100644 index 0000000..6fbfb74 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysLogMapper.java @@ -0,0 +1,63 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysLog; +import org.apache.ibatis.annotations.Param; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + *

+ * 系统日志表 Mapper 接口 + *

+ * + * @Author zhangweijian + * @since 2018-12-26 + */ +public interface SysLogMapper extends BaseMapper { + + /** + * 清空所有日志记录 + */ + public void removeAll(); + + /** + * 获取系统总访问次数 + * + * @return Long + */ + Long findTotalVisitCount(); + + //update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + + /** + * 获取系统今日访问次数 + * + * @param dayStart 开始时间 + * @param dayEnd 结束时间 + * @return Long + */ + Long findTodayVisitCount(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd); + + /** + * 获取系统今日访问 IP数 + * + * @param dayStart 开始时间 + * @param dayEnd 结束时间 + * @return Long + */ + Long findTodayIp(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd); + //update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + + /** + * 首页:根据时间统计访问数量/ip数量 + * + * @param dayStart + * @param dayEnd + * @param dbType + * @return + */ + List> findVisitCount(@Param("dayStart") Date dayStart, @Param("dayEnd") Date dayEnd, @Param("dbType") String dbType); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionDataRuleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionDataRuleMapper.java new file mode 100644 index 0000000..73d2114 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionDataRuleMapper.java @@ -0,0 +1,28 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysPermissionDataRule; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 权限规则 Mapper 接口 + *

+ * + * @Author huangzhilin + * @since 2019-04-01 + */ +public interface SysPermissionDataRuleMapper extends BaseMapper { + + /** + * 根据用户名和权限id查询 + * + * @param username + * @param permissionId + * @return + */ + public List queryDataRuleIds(@Param("username") String username, @Param("permissionId") String permissionId); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionMapper.java new file mode 100644 index 0000000..f55562a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPermissionMapper.java @@ -0,0 +1,66 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysPermission; +import digital.system.jeecg.system.model.TreeModel; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; +import org.apache.ibatis.annotations.Update; + +import java.util.List; + +/** + *

+ * 菜单权限表 Mapper 接口 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface SysPermissionMapper extends BaseMapper { + /** + * 通过父菜单ID查询子菜单 + * + * @param parentId + * @return + */ + public List queryListByParentId(@Param("parentId") String parentId); + + /** + * 根据用户查询用户权限 + * + * @param username 用户账户名称 + * @return List + */ + public List queryByUser(@Param("username") String username); + + /** + * 修改菜单状态字段: 是否子节点 + * + * @param id 菜单id + * @param leaf 叶子节点 + * @return int + */ + @Update("update sys_permission set is_leaf=#{leaf} where id = #{id}") + public int setMenuLeaf(@Param("id") String id, @Param("leaf") int leaf); + + /** + * 获取模糊匹配规则的数据权限URL + * + * @return List + */ + @Select("SELECT url FROM sys_permission WHERE del_flag = 0 and menu_type = 2 and url like '%*%'") + public List queryPermissionUrlWithStar(); + + + /** + * 根据用户账号查询菜单权限 + * + * @param sysPermission + * @param username + * @return + */ + public int queryCountByUsername(@Param("username") String username, @Param("permission") SysPermission sysPermission); + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPositionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPositionMapper.java new file mode 100644 index 0000000..f5947e4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysPositionMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysPosition; + +/** + * @Description: 职务表 + * @Author: zita + * @Date: 2019-09-19 + * @Version: V1.0 + */ +public interface SysPositionMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleIndexMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleIndexMapper.java new file mode 100644 index 0000000..74d25f0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleIndexMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysRoleIndex; + +/** + * @Description: 角色首页配置 + * @Author: zita + * @Date: 2022-03-25 + * @Version: V1.0 + */ +public interface SysRoleIndexMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleMapper.java new file mode 100644 index 0000000..d50782d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRoleMapper.java @@ -0,0 +1,36 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysRole; +import org.apache.ibatis.annotations.Delete; +import org.apache.ibatis.annotations.Param; + +/** + *

+ * 角色表 Mapper 接口 + *

+ * + * @Author scott + * @since 2018-12-19 + */ +public interface SysRoleMapper extends BaseMapper { + + /** + * @Description: 删除角色与用户关系 + * @Author scott + * @Date 2019/12/13 16:12 + */ + @Delete("delete from sys_user_role where role_id = #{roleId}") + void deleteRoleUserRelation(@Param("roleId") String roleId); + + + /** + * @param roleId + * @Description: 删除角色与权限关系 + * @Author scott + * @Date 2019/12/13 16:12 + */ + @Delete("delete from sys_role_permission where role_id = #{roleId}") + void deleteRolePermissionRelation(@Param("roleId") String roleId); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRolePermissionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRolePermissionMapper.java new file mode 100644 index 0000000..22ed138 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysRolePermissionMapper.java @@ -0,0 +1,16 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysRolePermission; + +/** + *

+ * 角色权限表 Mapper 接口 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface SysRolePermissionMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysTenantMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysTenantMapper.java new file mode 100644 index 0000000..370b657 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysTenantMapper.java @@ -0,0 +1,12 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysTenant; + +/** + * @Description: 租户mapper接口 + * @author: smcp + */ +public interface SysTenantMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysThirdAccountMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysThirdAccountMapper.java new file mode 100644 index 0000000..8bdf367 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysThirdAccountMapper.java @@ -0,0 +1,26 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysThirdAccount; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 第三方登录账号表 + * @Author: zita + * @Date: 2020-11-17 + * @Version: V1.0 + */ +public interface SysThirdAccountMapper extends BaseMapper { + + /** + * 通过 sysUsername 集合批量查询 + * + * @param sysUsernameArr username集合 + * @param thirdType 第三方类型 + * @return + */ + List selectThirdIdsByUsername(@Param("sysUsernameArr") String[] sysUsernameArr, @Param("thirdType") String thirdType); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserAgentMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserAgentMapper.java new file mode 100644 index 0000000..8c3fa85 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserAgentMapper.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysUserAgent; + +/** + * @Description: 用户代理人设置 + * @Author: zita + * @Date: 2019-04-17 + * @Version: V1.0 + */ +public interface SysUserAgentMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserDepartMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserDepartMapper.java new file mode 100644 index 0000000..61179c4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserDepartMapper.java @@ -0,0 +1,45 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.entity.SysUserDepart; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * @Description: 用户部门mapper接口 + * @author: smcp + */ +public interface SysUserDepartMapper extends BaseMapper { + + /** + * 通过用户id查询部门用户 + * + * @param userId 用户id + * @return List + */ + List getUserDepartByUid(@Param("userId") String userId); + + /** + * 查询指定部门下的用户 并且支持用户真实姓名模糊查询 + * + * @param orgCode + * @param realname + * @return + */ + List queryDepartUserList(@Param("orgCode") String orgCode, @Param("realname") String realname); + + /** + * 根据部门查询部门用户 + * + * @param page + * @param orgCode + * @param username + * @param realname + * @return + */ + IPage queryDepartUserPageList(Page page, @Param("orgCode") String orgCode, @Param("username") String username, @Param("realname") String realname); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserMapper.java new file mode 100644 index 0000000..5e75851 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserMapper.java @@ -0,0 +1,179 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import digital.bean.task.DpUser; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.model.SysUserSysDepartModel; +import digital.system.jeecg.system.vo.SysUserDepVo; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + *

+ * 用户表 Mapper 接口 + *

+ * + * @Author scott + * @since 2018-12-20 + */ +public interface SysUserMapper extends BaseMapper { + /** + * 通过用户账号查询用户信息 + * + * @param username + * @return + */ + public SysUser getUserByName(@Param("username") String username); + + /** + * 根据部门Id查询用户信息 + * + * @param page + * @param departId + * @param username 用户登录账户 + * @return + */ + IPage getUserByDepId(Page page, @Param("departId") String departId, @Param("username") String username); + + /** + * 根据用户Ids,查询用户所属部门名称信息 + * + * @param userIds + * @return + */ + List getDepNamesByUserIds(@Param("userIds") List userIds); + + /** + * 根据部门Ids,查询部门下用户信息 + * + * @param page + * @param departIds + * @param username 用户登录账户 + * @return + */ + IPage getUserByDepIds(Page page, @Param("departIds") List departIds, @Param("username") String username); + + /** + * 根据角色Id查询用户信息 + * + * @param page + * @param roleId 角色id + * @param username 用户登录账户 + * @return + */ + IPage getUserByRoleId(Page page, @Param("roleId") String roleId, @Param("username") String username); + + /** + * 根据用户名设置部门ID + * + * @param username + * @param orgCode + */ + void updateUserDepart(@Param("username") String username, @Param("orgCode") String orgCode); + + /** + * 根据手机号查询用户信息 + * + * @param phone + * @return + */ + public SysUser getUserByPhone(@Param("phone") String phone); + + + /** + * 根据邮箱查询用户信息 + * + * @param email + * @return + */ + public SysUser getUserByEmail(@Param("email") String email); + + /** + * 根据 orgCode 查询用户,包括子部门下的用户 + * + * @param page 分页对象, xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位(你可以继承Page实现自己的分页对象) + * @param orgCode + * @param userParams 用户查询条件,可为空 + * @return + */ + List getUserByOrgCode(IPage page, @Param("orgCode") String orgCode, @Param("userParams") SysUser userParams); + + + /** + * 查询 getUserByOrgCode 的Total + * + * @param orgCode + * @param userParams 用户查询条件,可为空 + * @return + */ + Integer getUserByOrgCodeTotal(@Param("orgCode") String orgCode, @Param("userParams") SysUser userParams); + + /** + * 批量删除角色与用户关系 + * + * @param roleIdArray + * @Author scott + * @Date 2019/12/13 16:10 + */ + void deleteBathRoleUserRelation(@Param("roleIdArray") String[] roleIdArray); + + /** + * 批量删除角色与权限关系 + * + * @param roleIdArray + * @Author scott + * @Date 2019/12/13 16:10 + */ + void deleteBathRolePermissionRelation(@Param("roleIdArray") String[] roleIdArray); + + /** + * 查询被逻辑删除的用户 + * + * @param wrapper + * @return List + */ + List selectLogicDeleted(@Param(Constants.WRAPPER) Wrapper wrapper); + + /** + * 还原被逻辑删除的用户 + * + * @param userIds 用户id + * @param entity + * @return int + */ + int revertLogicDeleted(@Param("userIds") String userIds, @Param("entity") SysUser entity); + + /** + * 彻底删除被逻辑删除的用户 + * + * @param userIds 多个用户id + * @return int + */ + int deleteLogicDeleted(@Param("userIds") String userIds); + + /** + * 更新空字符串为null【此写法有sql注入风险,禁止随便用】 + * + * @param fieldName + * @return int + */ + @Deprecated + int updateNullByEmptyString(@Param("fieldName") String fieldName); + + /** + * 根据部门Ids,查询部门下用户信息 + * + * @param departIds + * @param username 用户账户名称 + * @return + */ + List queryByDepIds(@Param("departIds") List departIds, @Param("username") String username); + + + DpUser getDeUserByName(String username); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserRoleMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserRoleMapper.java new file mode 100644 index 0000000..12f9ad2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysUserRoleMapper.java @@ -0,0 +1,38 @@ +package digital.system.jeecg.system.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import digital.system.jeecg.system.entity.SysUserRole; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.List; + +/** + *

+ * 用户角色表 Mapper 接口 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface SysUserRoleMapper extends BaseMapper { + + /** + * 通过用户账号查询角色集合 + * + * @param username 用户账号名称 + * @return List + */ + @Select("select role_code from sys_role where id in (select role_id from sys_user_role where user_id = (select id from sys_user where username=#{username}))") + List getRoleByUserName(@Param("username") String username); + + /** + * 通过用户账号查询角色Id集合 + * + * @param username 用户账号名称 + * @return List + */ + @Select("select id from sys_role where id in (select role_id from sys_user_role where user_id = (select id from sys_user where username=#{username}))") + List getRoleIdByUserName(@Param("username") String username); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysVersionMapper.java b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysVersionMapper.java new file mode 100644 index 0000000..b48ac4d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/SysVersionMapper.java @@ -0,0 +1,17 @@ +package digital.system.jeecg.system.mapper; + +import java.util.List; + +import digital.system.jeecg.system.entity.SysVersion; +import org.apache.ibatis.annotations.Param; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** + * @Description: sys_version + * @Author: jeecg-boot + * @Date: 2024-03-07 + * @Version: V1.0 + */ +public interface SysVersionMapper extends BaseMapper { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/DpUserMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/DpUserMapper.xml new file mode 100644 index 0000000..866d79c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/DpUserMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementMapper.xml new file mode 100644 index 0000000..d31928e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementSendMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementSendMapper.xml new file mode 100644 index 0000000..3ff20b8 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysAnnouncementSendMapper.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCategoryMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCategoryMapper.xml new file mode 100644 index 0000000..cb188f9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCategoryMapper.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCheckRuleMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCheckRuleMapper.xml new file mode 100644 index 0000000..85ea58c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysCheckRuleMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDataSourceMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDataSourceMapper.xml new file mode 100644 index 0000000..37f2629 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDataSourceMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartMapper.xml new file mode 100644 index 0000000..4341b0a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartMapper.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartPermissionMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartPermissionMapper.xml new file mode 100644 index 0000000..ae01eff --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartPermissionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleMapper.xml new file mode 100644 index 0000000..be69420 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleMapper.xml @@ -0,0 +1,16 @@ + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRolePermissionMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRolePermissionMapper.xml new file mode 100644 index 0000000..9c02d1b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRolePermissionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleUserMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleUserMapper.xml new file mode 100644 index 0000000..f3de5f0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDepartRoleUserMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictItemMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictItemMapper.xml new file mode 100644 index 0000000..1300076 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictItemMapper.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictMapper.xml new file mode 100644 index 0000000..fb0cafc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysDictMapper.xml @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysFillRuleMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysFillRuleMapper.xml new file mode 100644 index 0000000..f4f973e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysFillRuleMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysGatewayRouteMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysGatewayRouteMapper.xml new file mode 100644 index 0000000..87f05a0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysGatewayRouteMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysLogMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysLogMapper.xml new file mode 100644 index 0000000..4c94dec --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysLogMapper.xml @@ -0,0 +1,80 @@ + + + + + + + DELETE + FROM sys_log + + + + + + + + + + + + + + + diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionDataRuleMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionDataRuleMapper.xml new file mode 100644 index 0000000..b24103f --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionDataRuleMapper.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionMapper.xml new file mode 100644 index 0000000..87f1d7c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPermissionMapper.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPositionMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPositionMapper.xml new file mode 100644 index 0000000..691caaf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysPositionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysRoleIndexMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysRoleIndexMapper.xml new file mode 100644 index 0000000..b9a9a3c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysRoleIndexMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysTenantMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysTenantMapper.xml new file mode 100644 index 0000000..7cb7106 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysTenantMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysThirdAccountMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysThirdAccountMapper.xml new file mode 100644 index 0000000..b7f55bf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysThirdAccountMapper.xml @@ -0,0 +1,16 @@ + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserAgentMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserAgentMapper.xml new file mode 100644 index 0000000..32a7ba7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserAgentMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserDepartMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserDepartMapper.xml new file mode 100644 index 0000000..7e18b50 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserDepartMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserMapper.xml new file mode 100644 index 0000000..5967df4 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysUserMapper.xml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + UPDATE sys_user + SET org_code = #{orgCode} + where username = #{username} + + + + + + + + + + + FROM + sys_depart + INNER JOIN sys_user_depart ON sys_user_depart.dep_id = sys_depart.id + INNER JOIN sys_user ON sys_user.id = sys_user_depart.user_id + WHERE + + + + + + + sys_user.del_flag = 0 AND sys_depart.org_code LIKE #{bindOrgCode} + + + + AND sys_user.realname LIKE concat(concat('%',#{userParams.realname}),'%') + + + AND sys_user.work_no LIKE concat(concat('%',#{userParams.workNo}),'%') + + + + + + + + + + + + + delete from sys_user_role + where role_id in + + #{id} + + + + + delete from sys_role_permission + where role_id in + + #{id} + + + + + + + + + UPDATE + sys_user + SET del_flag = 0, + update_by = #{entity.updateBy}, + update_time = #{entity.updateTime} + WHERE del_flag = 1 + AND id IN (${userIds}) + + + + + DELETE + FROM sys_user + WHERE del_flag = 1 + AND id IN (${userIds}) + + + + + UPDATE sys_user + SET ${fieldName} = NULL + WHERE ${fieldName} = '' + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysVersionMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysVersionMapper.xml new file mode 100644 index 0000000..d338d1d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/SysVersionMapper.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/UploadVideoFileManageMapper.xml b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/UploadVideoFileManageMapper.xml new file mode 100644 index 0000000..c743bcd --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/mapper/xml/UploadVideoFileManageMapper.xml @@ -0,0 +1,12 @@ + + + + + + + \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/AnnouncementSendModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/AnnouncementSendModel.java new file mode 100644 index 0000000..69b84e6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/AnnouncementSendModel.java @@ -0,0 +1,99 @@ +package digital.system.jeecg.system.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; + +import java.io.Serializable; + +/** + * @Description: 用户通告阅读标记表 + * @Author: zita + * @Date: 2019-02-21 + * @Version: V1.0 + */ +@Data +public class AnnouncementSendModel implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private java.lang.String id; + /** + * 通告id + */ + private java.lang.String anntId; + /** + * 用户id + */ + private java.lang.String userId; + /** + * 标题 + */ + private java.lang.String titile; + /** + * 内容 + */ + private java.lang.String msgContent; + /** + * 发布人 + */ + private java.lang.String sender; + /** + * 优先级(L低,M中,H高) + */ + private java.lang.String priority; + /** + * 阅读状态 + */ + private java.lang.String readFlag; + /** + * 发布时间 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private java.util.Date sendTime; + /** + * 页数 + */ + private Integer pageNo; + /** + * 大小 + */ + private Integer pageSize; + /** + * 消息类型1:通知公告2:系统消息 + */ + private java.lang.String msgCategory; + /** + * 业务id + */ + private java.lang.String busId; + /** + * 业务类型 + */ + private java.lang.String busType; + /** + * 打开方式 组件:component 路由:url + */ + private java.lang.String openType; + /** + * 组件/路由 地址 + */ + private java.lang.String openPage; + + /** + * 业务类型查询(0.非bpm业务) + */ + private java.lang.String bizSource; + + /** + * 摘要 + */ + private java.lang.String msgAbstract; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/DepartIdModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/DepartIdModel.java new file mode 100644 index 0000000..0548ef9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/DepartIdModel.java @@ -0,0 +1,95 @@ +package digital.system.jeecg.system.model; + +import digital.system.jeecg.system.entity.SysDepart; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 部门表 封装树结构的部门的名称的实体类 + *

+ * + * @Author Steve + * @Since 2019-01-22 + */ +public class DepartIdModel implements Serializable { + + private static final long serialVersionUID = 1L; + List children = new ArrayList<>(); + /** + * 主键ID + */ + private String key; + /** + * 主键ID + */ + private String value; + /** + * 部门名称 + */ + private String title; + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + /** + * 将SysDepartTreeModel的部分数据放在该对象当中 + * + * @param treeModel + * @return + */ + public DepartIdModel convert(SysDepartTreeModel treeModel) { + this.key = treeModel.getId(); + this.value = treeModel.getId(); + this.title = treeModel.getDepartName(); + return this; + } + + /** + * 该方法为用户部门的实现类所使用 + * + * @param sysDepart + * @return + */ + public DepartIdModel convertByUserDepart(SysDepart sysDepart) { + this.key = sysDepart.getId(); + this.value = sysDepart.getId(); + this.title = sysDepart.getDepartName(); + return this; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/DuplicateCheckVo.java b/digital-system/src/main/java/digital/system/jeecg/system/model/DuplicateCheckVo.java new file mode 100644 index 0000000..1691cff --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/DuplicateCheckVo.java @@ -0,0 +1,45 @@ +package digital.system.jeecg.system.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.io.Serializable; + +/** + * @Title: DuplicateCheckVo + * @Description: 重复校验VO + * @Author 张代浩 + * @Date 2019-03-25 + * @Version V1.0 + */ +@Data +@ApiModel(value = "重复校验数据模型", description = "重复校验数据模型") +public class DuplicateCheckVo implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 表名 + */ + @ApiModelProperty(value = "表名", name = "tableName", example = "sys_log") + private String tableName; + + /** + * 字段名 + */ + @ApiModelProperty(value = "字段名", name = "fieldName", example = "id") + private String fieldName; + + /** + * 字段值 + */ + @ApiModelProperty(value = "字段值", name = "fieldVal", example = "1000") + private String fieldVal; + + /** + * 数据ID + */ + @ApiModelProperty(value = "数据ID", name = "dataId", example = "2000") + private String dataId; + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/SysDepartTreeModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/SysDepartTreeModel.java new file mode 100644 index 0000000..8b3b50c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/SysDepartTreeModel.java @@ -0,0 +1,402 @@ +package digital.system.jeecg.system.model; + +import digital.system.jeecg.system.entity.SysDepart; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Objects; + +/** + *

+ * 部门表 存储树结构数据的实体类 + *

+ * + * @Author Steve + * @Since 2019-01-22 + */ +public class SysDepartTreeModel implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 对应SysDepart中的id字段,前端数据树中的key + */ + private String key; + + /** + * 对应SysDepart中的id字段,前端数据树中的value + */ + private String value; + + /** + * 对应depart_name字段,前端数据树中的title + */ + private String title; + + + private boolean isLeaf; + // 以下所有字段均与SysDepart相同 + + private String id; + + private String parentId; + + private String departName; + + private String departNameEn; + + private String departNameAbbr; + + private Integer departOrder; + + private String description; + + private String orgCategory; + + private String orgType; + + private String orgCode; + + private String mobile; + + private String fax; + + private String address; + + private String memo; + + private String status; + + private String delFlag; + + private String qywxIdentifier; + + private String createBy; + + private Date createTime; + + private String updateBy; + + private Date updateTime; + + //update-begin---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids + /** + * 部门负责人ids + */ + private String directorUserIds; + //update-end---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增字段部门负责人ids + + private List children = new ArrayList<>(); + + + /** + * 将SysDepart对象转换成SysDepartTreeModel对象 + * + * @param sysDepart + */ + public SysDepartTreeModel(SysDepart sysDepart) { + this.key = sysDepart.getId(); + this.value = sysDepart.getId(); + this.title = sysDepart.getDepartName(); + this.id = sysDepart.getId(); + this.parentId = sysDepart.getParentId(); + this.departName = sysDepart.getDepartName(); + this.departNameEn = sysDepart.getDepartNameEn(); + this.departNameAbbr = sysDepart.getDepartNameAbbr(); + this.departOrder = sysDepart.getDepartOrder(); + this.description = sysDepart.getDescription(); + this.orgCategory = sysDepart.getOrgCategory(); + this.orgType = sysDepart.getOrgType(); + this.orgCode = sysDepart.getOrgCode(); + this.mobile = sysDepart.getMobile(); + this.fax = sysDepart.getFax(); + this.address = sysDepart.getAddress(); + this.memo = sysDepart.getMemo(); + this.status = sysDepart.getStatus(); + this.delFlag = sysDepart.getDelFlag(); + this.qywxIdentifier = sysDepart.getQywxIdentifier(); + this.createBy = sysDepart.getCreateBy(); + this.createTime = sysDepart.getCreateTime(); + this.updateBy = sysDepart.getUpdateBy(); + this.updateTime = sysDepart.getUpdateTime(); + this.directorUserIds = sysDepart.getDirectorUserIds(); + } + + public SysDepartTreeModel() { + } + + public static long getSerialVersionUID() { + return serialVersionUID; + } + + public boolean getIsLeaf() { + return isLeaf; + } + + public void setIsLeaf(boolean isleaf) { + this.isLeaf = isleaf; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + if (children == null) { + this.isLeaf = true; + } + this.children = children; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getDepartName() { + return departName; + } + + public void setDepartName(String departName) { + this.departName = departName; + } + + public String getOrgCategory() { + return orgCategory; + } + + public void setOrgCategory(String orgCategory) { + this.orgCategory = orgCategory; + } + + public String getOrgType() { + return orgType; + } + + public void setOrgType(String orgType) { + this.orgType = orgType; + } + + public String getOrgCode() { + return orgCode; + } + + public void setOrgCode(String orgCode) { + this.orgCode = orgCode; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public String getFax() { + return fax; + } + + public void setFax(String fax) { + this.fax = fax; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getMemo() { + return memo; + } + + public void setMemo(String memo) { + this.memo = memo; + } + + public String getDepartNameEn() { + return departNameEn; + } + + public void setDepartNameEn(String departNameEn) { + this.departNameEn = departNameEn; + } + + public String getDepartNameAbbr() { + return departNameAbbr; + } + + public void setDepartNameAbbr(String departNameAbbr) { + this.departNameAbbr = departNameAbbr; + } + + public Integer getDepartOrder() { + return departOrder; + } + + public void setDepartOrder(Integer departOrder) { + this.departOrder = departOrder; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDelFlag() { + return delFlag; + } + + public void setDelFlag(String delFlag) { + this.delFlag = delFlag; + } + + public String getQywxIdentifier() { + return qywxIdentifier; + } + + public void setQywxIdentifier(String qywxIdentifier) { + this.qywxIdentifier = qywxIdentifier; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getDirectorUserIds() { + return directorUserIds; + } + + public void setDirectorUserIds(String directorUserIds) { + this.directorUserIds = directorUserIds; + } + + /** + * 重写equals方法 + */ + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + SysDepartTreeModel model = (SysDepartTreeModel) o; + return Objects.equals(id, model.id) && + Objects.equals(parentId, model.parentId) && + Objects.equals(departName, model.departName) && + Objects.equals(departNameEn, model.departNameEn) && + Objects.equals(departNameAbbr, model.departNameAbbr) && + Objects.equals(departOrder, model.departOrder) && + Objects.equals(description, model.description) && + Objects.equals(orgCategory, model.orgCategory) && + Objects.equals(orgType, model.orgType) && + Objects.equals(orgCode, model.orgCode) && + Objects.equals(mobile, model.mobile) && + Objects.equals(fax, model.fax) && + Objects.equals(address, model.address) && + Objects.equals(memo, model.memo) && + Objects.equals(status, model.status) && + Objects.equals(delFlag, model.delFlag) && + Objects.equals(qywxIdentifier, model.qywxIdentifier) && + Objects.equals(createBy, model.createBy) && + Objects.equals(createTime, model.createTime) && + Objects.equals(updateBy, model.updateBy) && + Objects.equals(updateTime, model.updateTime) && + Objects.equals(directorUserIds, model.directorUserIds) && + Objects.equals(children, model.children); + } + + /** + * 重写hashCode方法 + */ + @Override + public int hashCode() { + + return Objects.hash(id, parentId, departName, departNameEn, departNameAbbr, + departOrder, description, orgCategory, orgType, orgCode, mobile, fax, address, + memo, status, delFlag, qywxIdentifier, createBy, createTime, updateBy, updateTime, + children, directorUserIds); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/SysDictTree.java b/digital-system/src/main/java/digital/system/jeecg/system/model/SysDictTree.java new file mode 100644 index 0000000..2bbfaa7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/SysDictTree.java @@ -0,0 +1,96 @@ +package digital.system.jeecg.system.model; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; +import digital.system.jeecg.system.entity.SysDict; + +import java.io.Serializable; +import java.util.Date; + +/** + *

+ * 字典表 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Data +@EqualsAndHashCode(callSuper = false) +@Accessors(chain = true) +public class SysDictTree implements Serializable { + + private static final long serialVersionUID = 1L; + + private String key; + + private String title; + + /** + * id + */ + @TableId(type = IdType.ASSIGN_ID) + private String id; + /** + * 字典类型,0 string,1 number类型,2 boolean + * 前端js对stirng类型和number类型 boolean 类型敏感,需要区分。在select 标签匹配的时候会用到 + * 默认为string类型 + */ + private Integer type; + + /** + * 字典名称 + */ + private String dictName; + + /** + * 字典编码 + */ + private String dictCode; + + /** + * 描述 + */ + private String description; + + /** + * 删除状态 + */ + @TableLogic + private Integer delFlag; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + public SysDictTree(SysDict node) { + this.id = node.getId(); + this.key = node.getId(); + this.title = node.getDictName(); + this.dictCode = node.getDictCode(); + this.description = node.getDescription(); + this.delFlag = node.getDelFlag(); + this.type = node.getType(); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/SysLoginModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/SysLoginModel.java new file mode 100644 index 0000000..294a6ab --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/SysLoginModel.java @@ -0,0 +1,55 @@ +package digital.system.jeecg.system.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * 登录表单 + * + * @Author scott + * @since 2019-01-18 + */ +@ApiModel(value = "登录对象", description = "登录对象") +public class SysLoginModel { + @ApiModelProperty(value = "账号") + private String username; + @ApiModelProperty(value = "密码") + private String password; + @ApiModelProperty(value = "验证码") + private String captcha; + @ApiModelProperty(value = "验证码key") + private String checkKey; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getCaptcha() { + return captcha; + } + + public void setCaptcha(String captcha) { + this.captcha = captcha; + } + + public String getCheckKey() { + return checkKey; + } + + public void setCheckKey(String checkKey) { + this.checkKey = checkKey; + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/SysPermissionTree.java b/digital-system/src/main/java/digital/system/jeecg/system/model/SysPermissionTree.java new file mode 100644 index 0000000..bb1363f --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/SysPermissionTree.java @@ -0,0 +1,431 @@ +package digital.system.jeecg.system.model; + +import io.swagger.annotations.ApiModelProperty; +import digital.system.jeecg.system.entity.SysPermission; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * @Description: 菜单树,封装树结构 + * @author: smcp + */ +public class SysPermissionTree implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * id + */ + private String id; + + private String key; + private String title; + + /** + * 父id + */ + private String parentId; + + /** + * 菜单名称 + */ + private String name; + + @ApiModelProperty(value = "繁体") + private String traditionalName; + + @ApiModelProperty(value = "英文") + private String englishName; + + /** + * 菜单权限编码 + */ + private String perms; + /** + * 权限策略1显示2禁用 + */ + private String permsType; + + /** + * 菜单图标 + */ + private String icon; + + /** + * 组件 + */ + private String component; + + /** + * 跳转网页链接 + */ + private String url; + + /** + * 一级菜单跳转地址 + */ + private String redirect; + + /** + * 菜单排序 + */ + private Double sortNo; + + /** + * 类型(0:一级菜单;1:子菜单 ;2:按钮权限) + */ + private Integer menuType; + + /** + * 是否叶子节点: 1:是 0:不是 + */ + private boolean isLeaf; + + /** + * 是否路由菜单: 0:不是 1:是(默认值1) + */ + private boolean route; + + + /** + * 是否路缓存页面: 0:不是 1:是(默认值1) + */ + private boolean keepAlive; + + + /** + * 描述 + */ + private String description; + + /** + * 删除状态 0正常 1已删除 + */ + private Integer delFlag; + + /** + * 创建人 + */ + private String createBy; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新人 + */ + private String updateBy; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * alwaysShow + */ + private boolean alwaysShow; + /** + * 是否隐藏路由菜单: 0否,1是(默认值0) + */ + private boolean hidden; + + /** + * 按钮权限状态(0无效1有效) + */ + private java.lang.String status; + + /*update_begin author:wuxianquan date:20190908 for:model增加字段 */ + /** + * 外链菜单打开方式 0/内部打开 1/外部打开 + */ + private boolean internalOrExternal; + /*update_end author:wuxianquan date:20190908 for:model增加字段 */ + private List children; + + public SysPermissionTree() { + } + + public SysPermissionTree(SysPermission permission) { + this.key = permission.getId(); + this.id = permission.getId(); + this.traditionalName = permission.getTraditionalName(); + this.englishName = permission.getEnglishName(); + this.perms = permission.getPerms(); + this.permsType = permission.getPermsType(); + this.component = permission.getComponent(); + this.createBy = permission.getCreateBy(); + this.createTime = permission.getCreateTime(); + this.delFlag = permission.getDelFlag(); + this.description = permission.getDescription(); + this.icon = permission.getIcon(); + this.isLeaf = permission.isLeaf(); + this.menuType = permission.getMenuType(); + this.name = permission.getName(); + this.parentId = permission.getParentId(); + this.sortNo = permission.getSortNo(); + this.updateBy = permission.getUpdateBy(); + this.updateTime = permission.getUpdateTime(); + this.redirect = permission.getRedirect(); + this.url = permission.getUrl(); + this.hidden = permission.isHidden(); + this.route = permission.isRoute(); + this.keepAlive = permission.isKeepAlive(); + this.alwaysShow = permission.isAlwaysShow(); + /*update_begin author:wuxianquan date:20190908 for:赋值 */ + this.internalOrExternal = permission.isInternalOrExternal(); + /*update_end author:wuxianquan date:20190908 for:赋值 */ + this.title = permission.getName(); + if (!permission.isLeaf()) { + this.children = new ArrayList(); + } + this.status = permission.getStatus(); + } + + public String getTraditionalName() { + return traditionalName; + } + + public void setTraditionalName(String traditionalName) { + this.traditionalName = traditionalName; + } + + public String getEnglishName() { + return englishName; + } + + public void setEnglishName(String englishName) { + this.englishName = englishName; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isLeaf() { + return isLeaf; + } + + public void setLeaf(boolean leaf) { + isLeaf = leaf; + } + + public boolean isKeepAlive() { + return keepAlive; + } + + public void setKeepAlive(boolean keepAlive) { + this.keepAlive = keepAlive; + } + + public boolean isAlwaysShow() { + return alwaysShow; + } + + public void setAlwaysShow(boolean alwaysShow) { + this.alwaysShow = alwaysShow; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getRedirect() { + return redirect; + } + + public void setRedirect(String redirect) { + this.redirect = redirect; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public boolean isHidden() { + return hidden; + } + + public void setHidden(boolean hidden) { + this.hidden = hidden; + } + + 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 getComponent() { + return component; + } + + public void setComponent(String component) { + this.component = component; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public Double getSortNo() { + return sortNo; + } + + public void setSortNo(Double sortNo) { + this.sortNo = sortNo; + } + + public Integer getMenuType() { + return menuType; + } + + public void setMenuType(Integer menuType) { + this.menuType = menuType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isRoute() { + return route; + } + + public void setRoute(boolean route) { + this.route = route; + } + + public Integer getDelFlag() { + return delFlag; + } + + public void setDelFlag(Integer delFlag) { + this.delFlag = delFlag; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getPerms() { + return perms; + } + + public void setPerms(String perms) { + this.perms = perms; + } + + public boolean getIsLeaf() { + return isLeaf; + } + + public void setIsLeaf(boolean isLeaf) { + this.isLeaf = isLeaf; + } + + public String getPermsType() { + return permsType; + } + + public void setPermsType(String permsType) { + this.permsType = permsType; + } + + public java.lang.String getStatus() { + return status; + } + + public void setStatus(java.lang.String status) { + this.status = status; + } + + /*update_begin author:wuxianquan date:20190908 for:get set方法 */ + public boolean isInternalOrExternal() { + return internalOrExternal; + } + + public void setInternalOrExternal(boolean internalOrExternal) { + this.internalOrExternal = internalOrExternal; + } + /*update_end author:wuxianquan date:20190908 for:get set 方法 */ +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/SysUserSysDepartModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/SysUserSysDepartModel.java new file mode 100644 index 0000000..fbb8f2c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/SysUserSysDepartModel.java @@ -0,0 +1,24 @@ +package digital.system.jeecg.system.model; + +import lombok.Data; + +/** + * 包含 SysUser 和 SysDepart 的 Model + * + * @author sunjianlei + */ +@Data +public class SysUserSysDepartModel { + + private String id; + private String realname; + private String workNo; + private String post; + private String telephone; + private String email; + private String phone; + private String departId; + private String departName; + private String avatar; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/ThirdLoginModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/ThirdLoginModel.java new file mode 100644 index 0000000..b81da98 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/ThirdLoginModel.java @@ -0,0 +1,76 @@ +package digital.system.jeecg.system.model; + +import lombok.Data; + +import java.io.Serializable; + +/** + * 第三方登录 信息存储 + * + * @author: smcp + */ +@Data +public class ThirdLoginModel implements Serializable { + private static final long serialVersionUID = 4098628709290780891L; + + /** + * 第三方登录 来源 + */ + private String source; + + /** + * 第三方登录 uuid + */ + private String uuid; + + /** + * 第三方登录 username + */ + private String username; + + /** + * 第三方登录 头像 + */ + private String avatar; + + /** + * 账号 后缀第三方登录 防止账号重复 + */ + private String suffix; + + /** + * 操作码 防止被攻击 + */ + private String operateCode; + + public ThirdLoginModel() { + + } + + /** + * 构造器 + * + * @param source + * @param uuid + * @param username + * @param avatar + */ + public ThirdLoginModel(String source, String uuid, String username, String avatar) { + this.source = source; + this.uuid = uuid; + this.username = username; + this.avatar = avatar; + } + + /** + * 获取登录账号名 + * + * @return + */ + public String getUserLoginAccount() { + if (suffix == null) { + return this.uuid; + } + return this.uuid + this.suffix; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/TreeModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/TreeModel.java new file mode 100644 index 0000000..091727c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/TreeModel.java @@ -0,0 +1,171 @@ +package digital.system.jeecg.system.model; + +import digital.system.jeecg.system.entity.SysPermission; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 树形列表用到 + * + * @author: smcp + */ +public class TreeModel implements Serializable { + + private static final long serialVersionUID = 4013193970046502756L; + + private String key; + + private String title; + + private String slotTitle; + + private boolean isLeaf; + + private String icon; + + private Integer ruleFlag; + + private Map scopedSlots; + private List children; + private String parentId; + private String label; + private String value; + + public TreeModel() { + + } + + public TreeModel(SysPermission permission) { + this.key = permission.getId(); + this.icon = permission.getIcon(); + this.parentId = permission.getParentId(); + this.title = permission.getName(); + this.slotTitle = permission.getName(); + this.value = permission.getId(); + this.isLeaf = permission.isLeaf(); + this.label = permission.getName(); + if (!permission.isLeaf()) { + this.children = new ArrayList(); + } + } + + public TreeModel(String key, String parentId, String slotTitle, Integer ruleFlag, boolean isLeaf) { + this.key = key; + this.parentId = parentId; + this.ruleFlag = ruleFlag; + this.slotTitle = slotTitle; + Map map = new HashMap(5); + map.put("title", "hasDatarule"); + this.scopedSlots = map; + this.isLeaf = isLeaf; + this.value = key; + if (!isLeaf) { + this.children = new ArrayList(); + } + } + + public Map getScopedSlots() { + return scopedSlots; + } + + public void setScopedSlots(Map scopedSlots) { + this.scopedSlots = scopedSlots; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean getIsLeaf() { + return isLeaf; + } + + public void setIsLeaf(boolean isLeaf) { + this.isLeaf = isLeaf; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + /** + * @return the label + */ + public String getLabel() { + return label; + } + + /** + * @param label the label to set + */ + public void setLabel(String label) { + this.label = label; + } + + /** + * @return the value + */ + public String getValue() { + return value; + } + + /** + * @param value the value to set + */ + public void setValue(String value) { + this.value = value; + } + + public String getSlotTitle() { + return slotTitle; + } + + public void setSlotTitle(String slotTitle) { + this.slotTitle = slotTitle; + } + + public Integer getRuleFlag() { + return ruleFlag; + } + + public void setRuleFlag(Integer ruleFlag) { + this.ruleFlag = ruleFlag; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/model/TreeSelectModel.java b/digital-system/src/main/java/digital/system/jeecg/system/model/TreeSelectModel.java new file mode 100644 index 0000000..decf694 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/model/TreeSelectModel.java @@ -0,0 +1,94 @@ +package digital.system.jeecg.system.model; + +import java.io.Serializable; +import java.util.List; + +/** + * 树形下拉框 + * + * @author: smcp + */ +public class TreeSelectModel implements Serializable { + + private static final long serialVersionUID = 9016390975325574747L; + + private String key; + + private String title; + + private boolean isLeaf; + + private String icon; + + private String parentId; + + private String value; + + private String code; + private List children; + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getParentId() { + return parentId; + } + + public void setParentId(String parentId) { + this.parentId = parentId; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public boolean isLeaf() { + return isLeaf; + } + + public void setLeaf(boolean isLeaf) { + this.isLeaf = isLeaf; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public List getChildren() { + return children; + } + + public void setChildren(List children) { + this.children = children; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/rule/CategoryCodeRule.java b/digital-system/src/main/java/digital/system/jeecg/system/rule/CategoryCodeRule.java new file mode 100644 index 0000000..b84ebe9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/rule/CategoryCodeRule.java @@ -0,0 +1,71 @@ +package digital.system.jeecg.system.rule; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import lombok.extern.slf4j.Slf4j; +import digital.base.handler.IFillRuleHandler; +import digital.system.jeecg.system.entity.SysCategory; +import digital.system.jeecg.system.mapper.SysCategoryMapper; +import digital.util.util.SpringContextUtils; +import digital.util.util.YouBianCodeUtil; +import digital.util.util.oConvertUtils; + +import java.util.List; + +/** + * @Author scott + * @Date 2019/12/9 11:32 + * @Description: 分类字典编码生成规则 + */ +@Slf4j +public class CategoryCodeRule implements IFillRuleHandler { + + public static final String ROOT_PID_VALUE = "0"; + + @Override + public Object execute(JSONObject params, JSONObject formData) { + log.info("系统自定义编码规则[category_code_rule],params:{} ,formData: {}", params, formData); + + String categoryPid = ROOT_PID_VALUE; + String categoryCode = null; + + if (formData != null && formData.size() > 0) { + Object obj = formData.get("pid"); + if (oConvertUtils.isNotEmpty(obj)) { + categoryPid = obj.toString(); + } + } else { + if (params != null) { + Object obj = params.get("pid"); + if (oConvertUtils.isNotEmpty(obj)) { + categoryPid = obj.toString(); + } + } + } + + /* + * 分成三种情况 + * 1.数据库无数据 调用YouBianCodeUtil.getNextYouBianCode(null); + * 2.添加子节点,无兄弟元素 YouBianCodeUtil.getSubYouBianCode(parentCode,null); + * 3.添加子节点有兄弟元素 YouBianCodeUtil.getNextYouBianCode(lastCode); + * */ + //找同类 确定上一个最大的code值 + LambdaQueryWrapper query = new LambdaQueryWrapper().eq(SysCategory::getPid, categoryPid).isNotNull(SysCategory::getCode).orderByDesc(SysCategory::getCode); + SysCategoryMapper baseMapper = (SysCategoryMapper) SpringContextUtils.getBean("sysCategoryMapper"); + List list = baseMapper.selectList(query); + if (list == null || list.size() == 0) { + if (ROOT_PID_VALUE.equals(categoryPid)) { + //情况1 + categoryCode = YouBianCodeUtil.getNextYouBianCode(null); + } else { + //情况2 + SysCategory parent = (SysCategory) baseMapper.selectById(categoryPid); + categoryCode = YouBianCodeUtil.getSubYouBianCode(parent.getCode(), null); + } + } else { + //情况3 + categoryCode = YouBianCodeUtil.getNextYouBianCode(list.get(0).getCode()); + } + return categoryCode; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/rule/OrderNumberRule.java b/digital-system/src/main/java/digital/system/jeecg/system/rule/OrderNumberRule.java new file mode 100644 index 0000000..bce469f --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/rule/OrderNumberRule.java @@ -0,0 +1,36 @@ +package digital.system.jeecg.system.rule; + +import com.alibaba.fastjson.JSONObject; +import org.apache.commons.lang3.RandomUtils; +import org.apache.commons.lang3.StringUtils; +import digital.base.handler.IFillRuleHandler; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 填值规则Demo:生成订单号 + * 【测试示例】 + */ +public class OrderNumberRule implements IFillRuleHandler { + + @Override + public Object execute(JSONObject params, JSONObject formData) { + String prefix = "CN"; + //订单前缀默认为CN 如果规则参数不为空,则取自定义前缀 + if (params != null) { + Object obj = params.get("prefix"); + if (obj != null) prefix = obj.toString(); + } + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + int random = RandomUtils.nextInt() + 10; + String value = prefix + format.format(new Date()) + random; + // 根据formData的值的不同,生成不同的订单号 + String name = formData.getString("name"); + if (!StringUtils.isEmpty(name)) { + value += name; + } + return value; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/rule/OrgCodeRule.java b/digital-system/src/main/java/digital/system/jeecg/system/rule/OrgCodeRule.java new file mode 100644 index 0000000..7f0f986 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/rule/OrgCodeRule.java @@ -0,0 +1,98 @@ +//package digital.system.jeecg.system.rule; +// +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import digital.base.handler.IFillRuleHandler; +//import digital.system.jeecg.system.entity.SysDepart; +//import digital.system.jeecg.system.service.ISysDepartService; +//import digital.util.util.SpringContextUtils; +//import digital.util.util.YouBianCodeUtil; +//import org.apache.poi.util.StringUtil; +// +//import java.util.ArrayList; +//import java.util.List; +// +///** +// * @Author scott +// * @Date 2019/12/9 11:33 +// * @Description: 机构编码生成规则 +// */ +//public class OrgCodeRule implements IFillRuleHandler { +// +// @Override +// public Object execute(JSONObject params, JSONObject formData) { +// ISysDepartService sysDepartService = (ISysDepartService) SpringContextUtils.getBean("sysDepartServiceImpl"); +// +// LambdaQueryWrapper query = new LambdaQueryWrapper(); +// LambdaQueryWrapper query1 = new LambdaQueryWrapper(); +// // 创建一个List集合,存储查询返回的所有SysDepart对象 +// List departList = new ArrayList<>(); +// String[] strArray = new String[2]; +// //定义部门类型 +// String orgType = ""; +// // 定义新编码字符串 +// String newOrgCode = ""; +// // 定义旧编码字符串 +// String oldOrgCode = ""; +// +// String parentId = null; +// if (formData != null && formData.size() > 0) { +// Object obj = formData.get("parentId"); +// if (obj != null) { +// parentId = obj.toString(); +// } +// } else { +// if (params != null) { +// Object obj = params.get("parentId"); +// if (obj != null) { +// parentId = obj.toString(); +// } +// } +// } +// +// //如果是最高级,则查询出同级的org_code, 调用工具类生成编码并返回 +// if (StringUtil.isNullOrEmpty(parentId)) { +// // 线判断数据库中的表是否为空,空则直接返回初始编码 +// query1.eq(SysDepart::getParentId, "").or().isNull(SysDepart::getParentId); +// query1.orderByDesc(SysDepart::getOrgCode); +// departList = sysDepartService.list(query1); +// if (departList == null || departList.size() == 0) { +// strArray[0] = YouBianCodeUtil.getNextYouBianCode(null); +// strArray[1] = "1"; +// return strArray; +// } else { +// SysDepart depart = departList.get(0); +// oldOrgCode = depart.getOrgCode(); +// orgType = depart.getOrgType(); +// newOrgCode = YouBianCodeUtil.getNextYouBianCode(oldOrgCode); +// } +// } else {//反之则查询出所有同级的部门,获取结果后有两种情况,有同级和没有同级 +// // 封装查询同级的条件 +// query.eq(SysDepart::getParentId, parentId); +// // 降序排序 +// query.orderByDesc(SysDepart::getOrgCode); +// // 查询出同级部门的集合 +// List parentList = sysDepartService.list(query); +// // 查询出父级部门 +// SysDepart depart = sysDepartService.getById(parentId); +// // 获取父级部门的Code +// String parentCode = depart.getOrgCode(); +// // 根据父级部门类型算出当前部门的类型 +// orgType = String.valueOf(Integer.valueOf(depart.getOrgType()) + 1); +// // 处理同级部门为null的情况 +// if (parentList == null || parentList.size() == 0) { +// // 直接生成当前的部门编码并返回 +// newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, null); +// } else { //处理有同级部门的情况 +// // 获取同级部门的编码,利用工具类 +// String subCode = parentList.get(0).getOrgCode(); +// // 返回生成的当前部门编码 +// newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, subCode); +// } +// } +// // 返回最终封装了部门编码和部门类型的数组 +// strArray[0] = newOrgCode; +// strArray[1] = orgType; +// return strArray; +// } +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/security/DictQueryBlackListHandler.java b/digital-system/src/main/java/digital/system/jeecg/system/security/DictQueryBlackListHandler.java new file mode 100644 index 0000000..d7474f6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/security/DictQueryBlackListHandler.java @@ -0,0 +1,57 @@ +package digital.system.jeecg.system.security; + + +import org.springframework.stereotype.Component; +import digital.base.constant.SymbolConstant; +import digital.util.security.AbstractQueryBlackListHandler; +import digital.util.util.oConvertUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * 字典组件 执行sql前校验 只校验表字典 + * dictCodeString格式如: + * table,text,code + * table where xxx,text,code + * table,text,code, where xxx + * + * @Author taoYan + * @Date 2022/3/23 21:10 + **/ +@Component("dictQueryBlackListHandler") +public class DictQueryBlackListHandler extends AbstractQueryBlackListHandler { + + @Override + protected List getQueryTableInfo(String dictCodeString) { + if (dictCodeString != null && dictCodeString.indexOf(SymbolConstant.COMMA) > 0) { + String[] arr = dictCodeString.split(SymbolConstant.COMMA); + if (arr.length != 3 && arr.length != 4) { + return null; + } + String tableName = getTableName(arr[0]); + QueryTable table = new QueryTable(tableName, ""); + // 无论什么场景 第二、三个元素一定是表的字段,直接add + table.addField(arr[1].trim()); + if (oConvertUtils.isNotEmpty(arr[2].trim())) { + table.addField(arr[2].trim()); + } + List list = new ArrayList<>(); + list.add(table); + return list; + } + return null; + } + + /** + * 取where前面的为:table name + * + * @param str + * @return + */ + private String getTableName(String str) { + String[] arr = str.split("\\s+(?i)where\\s+"); + return arr[0]; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/IDpUserService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/IDpUserService.java new file mode 100644 index 0000000..90a22bd --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/IDpUserService.java @@ -0,0 +1,27 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.bean.task.DpUser; + +/** + * @Description: dp_user + * @Author: jeecg-boot + * @Date: 2024-04-17 + * @Version: V1.0 + */ +public interface IDpUserService extends IService { + + /** + * 根据账号获取用户信息 + * + * @param phone + * @return + */ + DpUser getUserByAccount(String phone); + + DpUser addUser(String mobile); + + DpUser getByUserId(String id); + + DpUser getDeUserByName(String username); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementSendService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementSendService.java new file mode 100644 index 0000000..9aef368 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementSendService.java @@ -0,0 +1,35 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysAnnouncementSend; +import digital.system.jeecg.system.model.AnnouncementSendModel; + +import java.util.List; + +/** + * @Description: 用户通告阅读标记表 + * @Author: zita + * @Date: 2019-02-21 + * @Version: V1.0 + */ +public interface ISysAnnouncementSendService extends IService { + + /** + * 通过用户id查询用户通告阅读标记 + * + * @param userId 用户id + * @return + */ + public List queryByUserId(String userId); + + /** + * 获取我的消息 + * + * @param announcementSendModel + * @param page 当前页数 + * @return + */ + public Page getMyAnnouncementSendPage(Page page, AnnouncementSendModel announcementSendModel); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementService.java new file mode 100644 index 0000000..d815248 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysAnnouncementService.java @@ -0,0 +1,49 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysAnnouncement; + +/** + * @Description: 系统通告表 + * @Author: zita + * @Date: 2019-01-02 + * @Version: V1.0 + */ +public interface ISysAnnouncementService extends IService { + + /** + * 保存系统通告 + * + * @param sysAnnouncement + */ + public void saveAnnouncement(SysAnnouncement sysAnnouncement); + + /** + * 修改系统通告 + * + * @param sysAnnouncement + * @return + */ + public boolean upDateAnnouncement(SysAnnouncement sysAnnouncement); + + /** + * 保存系统通告 + * + * @param title 标题 + * @param msgContent 信息内容 + */ + public void saveSysAnnouncement(String title, String msgContent); + + /** + * 分页查询系统通告 + * + * @param page 当前页数 + * @param userId 用户id + * @param msgCategory 消息类型 + * @return Page + */ + public Page querySysCementPageByUserId(Page page, String userId, String msgCategory); + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCategoryService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCategoryService.java new file mode 100644 index 0000000..a867f82 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCategoryService.java @@ -0,0 +1,96 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysCategory; +import digital.system.jeecg.system.model.TreeSelectModel; +import digital.util.exception.JeecgBootException; + +import java.util.List; +import java.util.Map; + +/** + * @Description: 分类字典 + * @Author: zita + * @Date: 2019-05-29 + * @Version: V1.0 + */ +public interface ISysCategoryService extends IService { + + /** + * 根节点父ID的值 + */ + public static final String ROOT_PID_VALUE = "0"; + + /** + * 添加分类字典 + * + * @param sysCategory + */ + void addSysCategory(SysCategory sysCategory); + + /** + * 修改分类字典 + * + * @param sysCategory + */ + void updateSysCategory(SysCategory sysCategory); + + /** + * 根据父级编码加载分类字典的数据 + * + * @param pcode + * @return + * @throws JeecgBootException + */ + public List queryListByCode(String pcode) throws JeecgBootException; + + /** + * 根据pid查询子节点集合 + * + * @param pid + * @return + */ + public List queryListByPid(String pid); + + /** + * 根据pid查询子节点集合,支持查询条件 + * + * @param pid + * @param condition + * @return + */ + public List queryListByPid(String pid, Map condition); + + /** + * 根据code查询id + * + * @param code + * @return + */ + public String queryIdByCode(String code); + + /** + * 删除节点时同时删除子节点及修改父级节点 + * + * @param ids + */ + void deleteSysCategory(String ids); + + /** + * 分类字典控件数据回显[表单页面] + * + * @param ids + * @return + */ + List loadDictItem(String ids); + + /** + * 分类字典控件数据回显[表单页面] + * + * @param ids + * @param delNotExist 是否移除不存在的项,设为false如果某个key不存在数据库中,则直接返回key本身 + * @return + */ + List loadDictItem(String ids, boolean delNotExist); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCheckRuleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCheckRuleService.java new file mode 100644 index 0000000..580c5ab --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysCheckRuleService.java @@ -0,0 +1,33 @@ +package digital.system.jeecg.system.service; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysCheckRule; + +/** + * @Description: 编码校验规则 + * @Author: zita + * @Date: 2020-02-04 + * @Version: V1.0 + */ +public interface ISysCheckRuleService extends IService { + + /** + * 通过 code 获取规则 + * + * @param ruleCode + * @return + */ + SysCheckRule getByCode(String ruleCode); + + + /** + * 通过用户设定的自定义校验规则校验传入的值 + * + * @param checkRule + * @param value + * @return 返回 null代表通过校验,否则就是返回的错误提示文本 + */ + JSONObject checkValue(SysCheckRule checkRule, String value); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataLogService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataLogService.java new file mode 100644 index 0000000..c6f171b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataLogService.java @@ -0,0 +1,21 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDataLog; + +/** + * @Description: 数据日志service接口 + * @author: smcp + */ +public interface ISysDataLogService extends IService { + + /** + * 添加数据日志 + * + * @param tableName + * @param dataId + * @param dataContent + */ + public void addDataLog(String tableName, String dataId, String dataContent); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataSourceService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataSourceService.java new file mode 100644 index 0000000..1a61682 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDataSourceService.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDataSource; + +/** + * @Description: 多数据源管理 + * @Author: zita + * @Date: 2019-12-25 + * @Version: V1.0 + */ +public interface ISysDataSourceService extends IService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartPermissionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartPermissionService.java new file mode 100644 index 0000000..d877011 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartPermissionService.java @@ -0,0 +1,33 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDepartPermission; +import digital.system.jeecg.system.entity.SysPermissionDataRule; + +import java.util.List; + +/** + * @Description: 部门权限表 + * @Author: zita + * @Date: 2020-02-11 + * @Version: V1.0 + */ +public interface ISysDepartPermissionService extends IService { + /** + * 保存授权 将上次的权限和这次作比较 差异处理提高效率 + * + * @param departId + * @param permissionIds + * @param lastPermissionIds + */ + public void saveDepartPermission(String departId, String permissionIds, String lastPermissionIds); + + /** + * 根据部门id,菜单id获取数据规则 + * + * @param permissionId 菜单id + * @param departId 部门id + * @return + */ + List getPermRuleListByDeptIdAndPermId(String departId, String permissionId); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRolePermissionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRolePermissionService.java new file mode 100644 index 0000000..a055c57 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRolePermissionService.java @@ -0,0 +1,21 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDepartRolePermission; + +/** + * @Description: 部门角色权限 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +public interface ISysDepartRolePermissionService extends IService { + /** + * 保存授权 将上次的权限和这次作比较 差异处理提高效率 + * + * @param roleId + * @param permissionIds + * @param lastPermissionIds + */ + public void saveDeptRolePermission(String roleId, String permissionIds, String lastPermissionIds); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleService.java new file mode 100644 index 0000000..3b10043 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleService.java @@ -0,0 +1,25 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDepartRole; + +import java.util.List; + +/** + * @Description: 部门角色 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +public interface ISysDepartRoleService extends IService { + + /** + * 根据用户id,部门id查询可授权所有部门角色 + * + * @param orgCode + * @param userId + * @return + */ + List queryDeptRoleByDeptAndUser(String orgCode, String userId); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleUserService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleUserService.java new file mode 100644 index 0000000..ea4d9f6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartRoleUserService.java @@ -0,0 +1,32 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDepartRoleUser; + +import java.util.List; + +/** + * @Description: 部门角色人员信息 + * @Author: zita + * @Date: 2020-02-13 + * @Version: V1.0 + */ +public interface ISysDepartRoleUserService extends IService { + + /** + * 添加用户与部门关联 + * + * @param userId 用户id + * @param newRoleId 新的角色id + * @param oldRoleId 旧的角色id + */ + void deptRoleUserAdd(String userId, String newRoleId, String oldRoleId); + + /** + * 取消用户与部门关联,删除关联关系 + * + * @param userIds + * @param depId + */ + void removeDeptRoleUser(List userIds, String depId); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartService.java new file mode 100644 index 0000000..912c6a8 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDepartService.java @@ -0,0 +1,182 @@ +package digital.system.jeecg.system.service; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDepart; +import digital.system.jeecg.system.model.DepartIdModel; +import digital.system.jeecg.system.model.SysDepartTreeModel; + +import java.util.List; + +/** + *

+ * 部门表 服务实现类 + *

+ * + * @Author:Steve + * @Since: 2019-01-22 + */ +public interface ISysDepartService extends IService { + + /** + * 查询我的部门信息,并分节点进行显示 + * + * @param departIds 部门id + * @return + */ + List queryMyDeptTreeList(String departIds); + + /** + * 查询所有部门信息,并分节点进行显示 + * + * @return + */ + List queryTreeList(); + + + /** + * 查询所有部门信息,并分节点进行显示 + * + * @param ids 多个部门id + * @return + */ + List queryTreeList(String ids); + + /** + * 查询所有部门DepartId信息,并分节点进行显示 + * + * @return + */ + public List queryDepartIdTreeList(); + + /** + * 保存部门数据 + * + * @param sysDepart + * @param username 用户名 + */ + void saveDepartData(SysDepart sysDepart, String username); + + /** + * 更新depart数据 + * + * @param sysDepart + * @param username 用户名 + * @return + */ + Boolean updateDepartDataById(SysDepart sysDepart, String username); + + /** + * 删除depart数据 + * @param id + * @return + */ + /* boolean removeDepartDataById(String id); */ + + /** + * 根据关键字搜索相关的部门数据 + * + * @param keyWord + * @param myDeptSearch + * @param departIds 多个部门id + * @return + */ + List searchByKeyWord(String keyWord, String myDeptSearch, String departIds); + + /** + * 根据部门id删除并删除其可能存在的子级部门 + * + * @param id + * @return + */ + boolean delete(String id); + + /** + * 查询SysDepart集合 + * + * @param userId + * @return + */ + public List queryUserDeparts(String userId); + + /** + * 根据用户名查询部门 + * + * @param username + * @return + */ + List queryDepartsByUsername(String username); + + /** + * 根据部门id批量删除并删除其可能存在的子级部门 + * + * @param ids 多个部门id + * @return + */ + void deleteBatchWithChildren(List ids); + + /** + * 根据部门Id查询,当前和下级所有部门IDS + * + * @param departId + * @return + */ + List getSubDepIdsByDepId(String departId); + + /** + * 获取我的部门下级所有部门IDS + * + * @param departIds 多个部门id + * @return + */ + List getMySubDepIdsByDepId(String departIds); + + /** + * 根据关键字获取部门信息(通讯录) + * + * @param keyWord 搜索词 + * @return + */ + List queryTreeByKeyWord(String keyWord); + + /** + * 获取我的部门下级所有部门 + * + * @param parentId 父id + * @param ids 多个部门id + * @return + */ + List queryTreeListByPid(String parentId, String ids); + + /** + * 获取某个部门的所有父级部门的ID + * + * @param departId 根据departId查 + * @return JSONObject + */ + JSONObject queryAllParentIdByDepartId(String departId); + + /** + * 获取某个部门的所有父级部门的ID + * + * @param orgCode 根据orgCode查 + * @return JSONObject + */ + JSONObject queryAllParentIdByOrgCode(String orgCode); + + /** + * 获取公司信息 + * + * @param orgCode 部门编码 + * @return + */ + SysDepart queryCompByOrgCode(String orgCode); + + /** + * 获取下级部门 + * + * @param pid + * @return + */ + List queryDeptByPid(String pid); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictItemService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictItemService.java new file mode 100644 index 0000000..57f5579 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictItemService.java @@ -0,0 +1,25 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDictItem; + +import java.util.List; + +/** + *

+ * 服务类 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +public interface ISysDictItemService extends IService { + + /** + * 通过字典id查询字典项 + * + * @param mainId 字典id + * @return + */ + public List selectItemsByMainId(String mainId); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictService.java new file mode 100644 index 0000000..6a426e7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysDictService.java @@ -0,0 +1,279 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysDict; +import digital.system.jeecg.system.entity.SysDictItem; +import digital.system.jeecg.system.model.TreeSelectModel; +import digital.bean.jeecg.vo.DictModel; +import digital.bean.jeecg.vo.DictQuery; + +import java.util.List; +import java.util.Map; + +/** + *

+ * 字典表 服务类 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +public interface ISysDictService extends IService { + + /** + * 通过字典code获取字典数据 + * + * @param code + * @return + */ + public List queryDictItemsByCode(String code); + + /** + * 查询有效的数据字典项 + * + * @param code + * @return + */ + List queryEnableDictItemsByCode(String code); + + /** + * 通过多个字典code获取字典数据 + * + * @param dictCodeList + * @return key = 字典code,value=对应的字典选项 + */ + Map> queryDictItemsByCodeList(List dictCodeList); + + /** + * 登录加载系统字典 + * + * @return + */ + public Map> queryAllDictItems(); + + /** + * 查通过查询指定table的 text code 获取字典 + * + * @param table + * @param text + * @param code + * @return + */ + @Deprecated + List queryTableDictItemsByCode(String table, String text, String code); + + /** + * 通过查询指定table的 text code 获取字典(指定查询条件) + * + * @param table + * @param text + * @param code + * @param filterSql + * @return + */ + @Deprecated + public List queryTableDictItemsByCodeAndFilter(String table, String text, String code, String filterSql); + + /** + * 通过字典code及字典项的value获取字典文本 + * + * @param code + * @param key + * @return + */ + public String queryDictTextByKey(String code, String key); + + /** + * 可通过多个字典code查询翻译文本 + * + * @param dictCodeList 多个字典code + * @param keys 数据列表 + * @return + */ + Map> queryManyDictByKeys(List dictCodeList, List keys); + + /** + * 通过查询指定table的 text code key 获取字典值 + * + * @param table + * @param text + * @param code + * @param key + * @return + */ + @Deprecated + String queryTableDictTextByKey(String table, String text, String code, String key); + + /** + * 通过查询指定table的 text code key 获取字典值,可批量查询 + * + * @param table + * @param text + * @param code + * @param keys + * @return + */ + List queryTableDictTextByKeys(String table, String text, String code, List keys); + + /** + * 通过查询指定table的 text code key 获取字典值,包含value + * + * @param table 表名 + * @param text + * @param code + * @param keys + * @return + */ + @Deprecated + List queryTableDictByKeys(String table, String text, String code, String keys); + + /** + * 通过查询指定table的 text code key 获取字典值,包含value + * + * @param table + * @param text + * @param code + * @param keys + * @param delNotExist + * @return + */ + @Deprecated + List queryTableDictByKeys(String table, String text, String code, String keys, boolean delNotExist); + + /** + * 根据字典类型删除关联表中其对应的数据 + * + * @param sysDict + * @return + */ + boolean deleteByDictId(SysDict sysDict); + + /** + * 添加一对多 + * + * @param sysDict + * @param sysDictItemList + * @return Integer + */ + public Integer saveMain(SysDict sysDict, List sysDictItemList); + + /** + * 查询所有部门 作为字典信息 id -->value,departName -->text + * + * @return + */ + public List queryAllDepartBackDictModel(); + + /** + * 查询所有用户 作为字典信息 username -->value,realname -->text + * + * @return + */ + public List queryAllUserBackDictModel(); + + /** + * 通过关键字查询字典表 + * + * @param table + * @param text + * @param code + * @param keyword + * @return + */ + @Deprecated + public List queryTableDictItems(String table, String text, String code, String keyword); + + /** + * 查询字典表数据 只查询前10条 + * + * @param table + * @param text + * @param code + * @param keyword + * @param condition + * @param pageSize 每页条数 + * @return + */ + public List queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize); + + /** + * 查询字典表所有数据 + * + * @param table + * @param text + * @param code + * @param condition + * @param keyword + * @return + */ + public List queryAllTableDictItems(String table, String text, String code, String condition, String keyword); + + /** + * 根据表名、显示字段名、存储字段名 查询树 + * + * @param table + * @param text + * @param code + * @param pidField + * @param pid + * @param hasChildField + * @param query + * @return + */ + @Deprecated + List queryTreeList(Map query, String table, String text, String code, String pidField, String pid, String hasChildField); + + /** + * 真实删除 + * + * @param id + */ + public void deleteOneDictPhysically(String id); + + /** + * 修改delFlag + * + * @param delFlag + * @param id + */ + public void updateDictDelFlag(int delFlag, String id); + + /** + * 查询被逻辑删除的数据 + * + * @return + */ + public List queryDeleteList(); + + /** + * 分页查询 + * + * @param query + * @param pageSize + * @param pageNo + * @return + */ + @Deprecated + public List queryDictTablePageList(DictQuery query, int pageSize, int pageNo); + + /** + * 获取字典数据 + * + * @param dictCode 字典code + * @param dictCode 表名,文本字段,code字段 | 举例:sys_user,realname,id + * @return + */ + List getDictItems(String dictCode); + + /** + * 【JSearchSelectTag下拉搜索组件专用接口】 + * 大数据量的字典表 走异步加载 即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword + * @param pageSize 每页条数 + * @return + */ + List loadDict(String dictCode, String keyword, Integer pageSize); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysFillRuleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysFillRuleService.java new file mode 100644 index 0000000..09a9242 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysFillRuleService.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysFillRule; + +/** + * @Description: 填值规则 + * @Author: zita + * @Date: 2019-11-07 + * @Version: V1.0 + */ +public interface ISysFillRuleService extends IService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysGatewayRouteService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysGatewayRouteService.java new file mode 100644 index 0000000..1428482 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysGatewayRouteService.java @@ -0,0 +1,41 @@ +//package digital.system.jeecg.system.service; +// +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.extension.service.IService; +//import digital.system.jeecg.system.entity.SysGatewayRoute; +// +///** +// * @Description: gateway路由管理 +// * @Author: zita +// * @Date: 2020-05-26 +// * @Version: V1.0 +// */ +//public interface ISysGatewayRouteService extends IService { +// +// /** +// * 添加所有的路由信息到redis +// * +// * @param key +// */ +// void addRoute2Redis(String key); +// +// /** +// * 删除路由 +// * +// * @param id +// */ +// void deleteById(String id); +// +// /** +// * 保存路由配置 +// * +// * @param array +// */ +// void updateAll(JSONObject array); +// +// /** +// * 清空redis中的route信息 +// */ +// void clearRedis(); +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysLogService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysLogService.java new file mode 100644 index 0000000..24d01d6 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysLogService.java @@ -0,0 +1,61 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysLog; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + *

+ * 系统日志表 服务类 + *

+ * + * @Author zhangweijian + * @since 2018-12-26 + */ +public interface ISysLogService extends IService { + + /** + * 清空所有日志记录 + */ + public void removeAll(); + + /** + * 获取系统总访问次数 + * + * @return Long + */ + Long findTotalVisitCount(); + + //update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + + /** + * 获取系统今日访问次数 + * + * @param dayStart + * @param dayEnd + * @return Long + */ + Long findTodayVisitCount(Date dayStart, Date dayEnd); + + /** + * 获取系统今日访问 IP数 + * + * @param dayStart 开始时间 + * @param dayEnd 结束时间 + * @return Long + */ + Long findTodayIp(Date dayStart, Date dayEnd); + //update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + + /** + * 首页:根据时间统计访问数量/ip数量 + * + * @param dayStart + * @param dayEnd + * @return + */ + List> findVisitCount(Date dayStart, Date dayEnd); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionDataRuleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionDataRuleService.java new file mode 100644 index 0000000..f4cbf88 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionDataRuleService.java @@ -0,0 +1,59 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysPermissionDataRule; + +import java.util.List; + +/** + *

+ * 菜单权限规则 服务类 + *

+ * + * @Author huangzhilin + * @since 2019-04-01 + */ +public interface ISysPermissionDataRuleService extends IService { + + /** + * 根据菜单id查询其对应的权限数据 + * + * @param permissionId + * @return List + */ + List getPermRuleListByPermId(String permissionId); + + /** + * 根据页面传递的参数查询菜单权限数据 + * + * @param permRule + * @return + */ + List queryPermissionRule(SysPermissionDataRule permRule); + + + /** + * 根据菜单ID和用户名查找数据权限配置信息 + * + * @param permissionId + * @param username + * @return + */ + List queryPermissionDataRules(String username, String permissionId); + + /** + * 新增菜单权限配置 修改菜单rule_flag + * + * @param sysPermissionDataRule + */ + public void savePermissionDataRule(SysPermissionDataRule sysPermissionDataRule); + + /** + * 删除菜单权限配置 判断菜单还有无权限 + * + * @param dataRuleId + */ + public void deletePermissionDataRule(String dataRuleId); + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionService.java new file mode 100644 index 0000000..3a792b1 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPermissionService.java @@ -0,0 +1,100 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysPermission; +import digital.system.jeecg.system.model.TreeModel; +import digital.util.exception.JeecgBootException; + +import java.util.List; + +/** + *

+ * 菜单权限表 服务类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface ISysPermissionService extends IService { + + /** + * 通过父id查询菜单 + * + * @param parentId 父id + * @return + */ + public List queryListByParentId(String parentId); + + /** + * 真实删除 + * + * @param id 菜单id + * @throws JeecgBootException + */ + public void deletePermission(String id) throws JeecgBootException; + + /** + * 逻辑删除 + * + * @param id 菜单id + * @throws JeecgBootException + */ + public void deletePermissionLogical(String id) throws JeecgBootException; + + /** + * 添加菜单 + * + * @param sysPermission SysPermission对象 + * @throws JeecgBootException + */ + public void addPermission(SysPermission sysPermission) throws JeecgBootException; + + /** + * 编辑菜单 + * + * @param sysPermission SysPermission对象 + * @throws JeecgBootException + */ + public void editPermission(SysPermission sysPermission) throws JeecgBootException; + + /** + * 获取登录用户拥有的权限 + * + * @param username 用户名 + * @return + */ + public List queryByUser(String username); + + /** + * 根据permissionId删除其关联的SysPermissionDataRule表中的数据 + * + * @param id + * @return + */ + public void deletePermRuleByPermId(String id); + + /** + * 查询出带有特殊符号的菜单地址的集合 + * + * @return + */ + public List queryPermissionUrlWithStar(); + + /** + * 判断用户否拥有权限 + * + * @param username + * @param sysPermission + * @return + */ + public boolean hasPermission(String username, SysPermission sysPermission); + + /** + * 根据用户和请求地址判断是否有此权限 + * + * @param username + * @param url + * @return + */ + public boolean hasPermission(String username, String url); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPositionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPositionService.java new file mode 100644 index 0000000..5bbf7e1 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysPositionService.java @@ -0,0 +1,22 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysPosition; + +/** + * @Description: 职务表 + * @Author: zita + * @Date: 2019-09-19 + * @Version: V1.0 + */ +public interface ISysPositionService extends IService { + + /** + * 通过code查询 + * + * @param code 职务编码 + * @return SysPosition + */ + SysPosition getByCode(String code); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleIndexService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleIndexService.java new file mode 100644 index 0000000..1067ee9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleIndexService.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysRoleIndex; + +/** + * @Description: 角色首页配置 + * @Author: zita + * @Date: 2022-03-25 + * @Version: V1.0 + */ +public interface ISysRoleIndexService extends IService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRolePermissionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRolePermissionService.java new file mode 100644 index 0000000..e97d2bf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRolePermissionService.java @@ -0,0 +1,33 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysRolePermission; + +/** + *

+ * 角色权限表 服务类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface ISysRolePermissionService extends IService { + + /** + * 保存授权/先删后增 + * + * @param roleId + * @param permissionIds + */ + public void saveRolePermission(String roleId, String permissionIds); + + /** + * 保存授权 将上次的权限和这次作比较 差异处理提高效率 + * + * @param roleId + * @param permissionIds + * @param lastPermissionIds + */ + public void saveRolePermission(String roleId, String permissionIds, String lastPermissionIds); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleService.java new file mode 100644 index 0000000..c50293a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysRoleService.java @@ -0,0 +1,45 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysRole; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.springframework.web.multipart.MultipartFile; +import digital.base.vo.Result; + +/** + *

+ * 角色表 服务类 + *

+ * + * @Author scott + * @since 2018-12-19 + */ +public interface ISysRoleService extends IService { + + /** + * 导入 excel ,检查 roleCode 的唯一性 + * + * @param file + * @param params + * @return + * @throws Exception + */ + Result importExcelCheckRoleCode(MultipartFile file, ImportParams params) throws Exception; + + /** + * 删除角色 + * + * @param roleid + * @return + */ + public boolean deleteRole(String roleid); + + /** + * 批量删除角色 + * + * @param roleids + * @return + */ + public boolean deleteBatchRole(String[] roleids); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysTenantService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysTenantService.java new file mode 100644 index 0000000..ec1bf0e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysTenantService.java @@ -0,0 +1,39 @@ +//package digital.system.jeecg.system.service; +// +//import com.baomidou.mybatisplus.extension.service.IService; +//import digital.system.jeecg.system.entity.SysTenant; +// +//import java.util.Collection; +//import java.util.List; +// +///** +// * @Description: 租户service接口 +// * @author: smcp +// */ +//public interface ISysTenantService extends IService { +// +// /** +// * 查询有效的租户 +// * +// * @param idList +// * @return +// */ +// List queryEffectiveTenant(Collection idList); +// +// /** +// * 返回某个租户被多少个用户引用了 +// * +// * @param id +// * @return +// */ +// Long countUserLinkTenant(String id); +// +// /** +// * 根据ID删除租户,会判断是否已被引用 +// * +// * @param id +// * @return +// */ +// boolean removeTenantById(String id); +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysThirdAccountService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysThirdAccountService.java new file mode 100644 index 0000000..1338d6b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysThirdAccountService.java @@ -0,0 +1,69 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysThirdAccount; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.model.ThirdLoginModel; + +import java.util.List; + +/** + * @Description: 第三方登录账号表 + * @Author: zita + * @Date: 2020-11-17 + * @Version: V1.0 + */ +public interface ISysThirdAccountService extends IService { + /** + * 更新第三方账户信息 + * + * @param sysUser SysUser对象 + * @param thirdUserUuid 第三方id + */ + void updateThirdUserId(SysUser sysUser, String thirdUserUuid); + + /** + * 创建第三方用户 + * + * @param phone 手机号 + * @param thirdUserUuid 第三方id + * @return SysUser + */ + SysUser createUser(String phone, String thirdUserUuid); + + /** + * 根据本地userId查询数据 + * + * @param sysUserId 用户id + * @param thirdType 第三方登录类型 + * @return SysThirdAccount + */ + SysThirdAccount getOneBySysUserId(String sysUserId, String thirdType); + + /** + * 根据第三方userId查询数据 + * + * @param thirdUserId 第三方id + * @param thirdType 第三方登录类型 + * @return SysThirdAccount + */ + SysThirdAccount getOneByThirdUserId(String thirdUserId, String thirdType); + + /** + * 通过 sysUsername 集合批量查询 + * + * @param sysUsernameArr username集合 + * @param thirdType 第三方类型 + * @return + */ + List listThirdUserIdByUsername(String[] sysUsernameArr, String thirdType); + + /** + * 创建新用户 + * + * @param tlm 第三方登录信息 + * @return SysThirdAccount + */ + SysThirdAccount saveThirdUser(ThirdLoginModel tlm); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserAgentService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserAgentService.java new file mode 100644 index 0000000..2f4723a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserAgentService.java @@ -0,0 +1,14 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysUserAgent; + +/** + * @Description: 用户代理人设置 + * @Author: zita + * @Date: 2019-04-17 + * @Version: V1.0 + */ +public interface ISysUserAgentService extends IService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserDepartService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserDepartService.java new file mode 100644 index 0000000..d4711ce --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserDepartService.java @@ -0,0 +1,59 @@ +package digital.system.jeecg.system.service; + + +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.entity.SysUserDepart; +import digital.system.jeecg.system.model.DepartIdModel; + +import java.util.List; + +/** + *

+ * SysUserDpeart用户组织机构service + *

+ * + * @Author ZhiLin + */ +public interface ISysUserDepartService extends IService { + + + /** + * 根据指定用户id查询部门信息 + * + * @param userId + * @return + */ + List queryDepartIdsOfUser(String userId); + + + /** + * 根据部门id查询用户信息 + * + * @param depId + * @return + */ + List queryUserByDepId(String depId); + + /** + * 根据部门code,查询当前部门和下级部门的用户信息 + * + * @param depCode 部门code + * @param realname 真实姓名 + * @return List + */ + List queryUserByDepCode(String depCode, String realname); + + /** + * 用户组件数据查询 + * + * @param departId + * @param username + * @param pageSize + * @param pageNo + * @return + */ + IPage queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserRoleService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserRoleService.java new file mode 100644 index 0000000..6a88497 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserRoleService.java @@ -0,0 +1,15 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysUserRole; + +/** + *

+ * 用户角色表 服务类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +public interface ISysUserRoleService extends IService { +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserService.java new file mode 100644 index 0000000..1dde19a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysUserService.java @@ -0,0 +1,322 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; +import digital.base.vo.Result; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.model.SysUserSysDepartModel; +import digital.util.util.SysUserCacheInfo; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + *

+ * 用户表 服务类 + *

+ * + * @Author scott + * @since 2018-12-20 + */ +public interface ISysUserService extends IService { + /** + * 重置密码 + * + * @param username + * @param oldpassword + * @param newpassword + * @param confirmpassword + * @return + */ + public Result resetPassword(String username, String oldpassword, String newpassword, String confirmpassword); + + /** + * 修改密码 + * + * @param sysUser + * @return + */ + public Result changePassword(SysUser sysUser); + + /** + * 删除用户 + * + * @param userId + * @return + */ + public boolean deleteUser(String userId); + + /** + * 批量删除用户 + * + * @param userIds + * @return + */ + public boolean deleteBatchUsers(String userIds); + + /** + * 根据用户名查询 + * + * @param username 用户名 + * @return SysUser + */ + public SysUser getUserByName(String username); + + /** + * 添加用户和用户角色关系 + * + * @param user + * @param roles + */ + public void addUserWithRole(SysUser user, String roles); + + + /** + * 修改用户和用户角色关系 + * + * @param user + * @param roles + */ + public void editUserWithRole(SysUser user, String roles); + + /** + * 获取用户的授权角色 + * + * @param username + * @return + */ + public List getRole(String username); + + /** + * 查询用户信息包括 部门信息 + * + * @param username + * @return + */ + public SysUserCacheInfo getCacheUser(String username); + + /** + * 根据部门Id查询 + * + * @param page + * @param departId 部门id + * @param username 用户账户名称 + * @return + */ + public IPage getUserByDepId(Page page, String departId, String username); + + /** + * 根据部门Ids查询 + * + * @param page + * @param departIds 部门id集合 + * @param username 用户账户名称 + * @return + */ + public IPage getUserByDepIds(Page page, List departIds, String username); + + /** + * 根据 userIds查询,查询用户所属部门的名称(多个部门名逗号隔开) + * + * @param userIds + * @return + */ + public Map getDepNamesByUserIds(List userIds); + + /** + * 根据部门 Id 和 QueryWrapper 查询 + * + * @param page + * @param departId + * @param queryWrapper + * @return + */ + public IPage getUserByDepartIdAndQueryWrapper(Page page, String departId, QueryWrapper queryWrapper); + + /** + * 根据 orgCode 查询用户,包括子部门下的用户 + * + * @param orgCode + * @param userParams 用户查询条件,可为空 + * @param page 分页参数 + * @return + */ + IPage queryUserByOrgCode(String orgCode, SysUser userParams, IPage page); + + /** + * 根据角色Id查询 + * + * @param page + * @param roleId 角色id + * @param username 用户账户名称 + * @return + */ + public IPage getUserByRoleId(Page page, String roleId, String username); + + /** + * 通过用户名获取用户角色集合 + * + * @param username 用户名 + * @return 角色集合 + */ + Set getUserRolesSet(String username); + + /** + * 通过用户名获取用户权限集合 + * + * @param username 用户名 + * @return 权限集合 + */ + Set getUserPermissionsSet(String username); + + /** + * 根据用户名设置部门ID + * + * @param username + * @param orgCode + */ + void updateUserDepart(String username, String orgCode); + + /** + * 根据手机号获取用户名和密码 + * + * @param phone 手机号 + */ + public SysUser getUserByPhone(String phone); + + + /** + * 根据邮箱获取用户 + * + * @param email 邮箱 + * @return SysUser + */ + public SysUser getUserByEmail(String email); + + + /** + * 添加用户和用户部门关系 + * + * @param user + * @param selectedParts + */ + void addUserWithDepart(SysUser user, String selectedParts); + + /** + * 编辑用户和用户部门关系 + * + * @param user + * @param departs + */ + void editUserWithDepart(SysUser user, String departs); + + /** + * 校验用户是否有效 + * + * @param sysUser + * @return + */ + Result checkUserIsEffective(SysUser sysUser); + + /** + * 查询被逻辑删除的用户 + * + * @return List + */ + List queryLogicDeleted(); + + /** + * 查询被逻辑删除的用户(可拼装查询条件) + * + * @param wrapper + * @return List + */ + List queryLogicDeleted(LambdaQueryWrapper wrapper); + + /** + * 还原被逻辑删除的用户 + * + * @param userIds 存放用户id集合 + * @param updateEntity + * @return boolean + */ + boolean revertLogicDeleted(List userIds, SysUser updateEntity); + + /** + * 彻底删除被逻辑删除的用户 + * + * @param userIds 存放用户id集合 + * @return boolean + */ + boolean removeLogicDeleted(List userIds); + + /** + * 更新手机号、邮箱空字符串为 null + * + * @return boolean + */ + @Transactional(rollbackFor = Exception.class) + boolean updateNullPhoneEmail(); + + /** + * 保存第三方用户信息 + * + * @param sysUser + */ + void saveThirdUser(SysUser sysUser); + + /** + * 根据部门Ids查询 + * + * @param departIds 部门id集合 + * @param username 用户账户名称 + * @return + */ + List queryByDepIds(List departIds, String username); + + /** + * 保存用户 + * + * @param user 用户 + * @param selectedRoles 选择的角色id,多个以逗号隔开 + * @param selectedDeparts 选择的部门id,多个以逗号隔开 + */ + void saveUser(SysUser user, String selectedRoles, String selectedDeparts); + + /** + * 编辑用户 + * + * @param user 用户 + * @param roles 选择的角色id,多个以逗号隔开 + * @param departs 选择的部门id,多个以逗号隔开 + */ + void editUser(SysUser user, String roles, String departs); + + /** + * userId转为username + * + * @param userIdList + * @return List + */ + List userIdToUsername(Collection userIdList); + + /** + * 获取用户是否有使用次数 + * @param discordId + * @return + */ + Result getUserTimes(String discordId); + + /** + * 第三方discord登录 + * @param jsonObject + * @return + */ +// Result loginWithDiscord(JSONObject jsonObject); +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/ISysVersionService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysVersionService.java new file mode 100644 index 0000000..4c1c6e2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/ISysVersionService.java @@ -0,0 +1,13 @@ +package digital.system.jeecg.system.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import digital.system.jeecg.system.entity.SysVersion; + + +public interface ISysVersionService extends IService { + + public String queryVersion(); + + public SysVersion queryVersionInfo(); + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/IThirdAppService.java b/digital-system/src/main/java/digital/system/jeecg/system/service/IThirdAppService.java new file mode 100644 index 0000000..0e0b474 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/IThirdAppService.java @@ -0,0 +1,96 @@ +//package digital.system.jeecg.system.service; +// +// +//import digital.bean.jeecg.dto.message.MessageDTO; +//import digital.system.jeecg.system.vo.thirdapp.SyncInfoVo; +// +//import java.util.List; +// +///** +// * 第三方App对接 +// * +// * @author: smcp +// */ +//public interface IThirdAppService { +// +// /** +// * 获取AccessToken +// * +// * @return String +// */ +// String getAccessToken(); +// +// /** +// * 将本地部门同步到第三方App
+// * 同步方向:本地 --> 第三方APP +// * 同步逻辑:
+// * 1. 先判断是否同步过,有则修改,无则创建;
+// * 2. 本地没有但第三方App里有则删除第三方App里的。 +// * +// * @param ids +// * @return 成功返回true +// */ +// SyncInfoVo syncLocalDepartmentToThirdApp(String ids); +// +// /** +// * 将第三方App部门同步到本地
+// * 同步方向:第三方APP --> 本地 +// * 同步逻辑:
+// * 1. 先判断是否同步过,有则修改,无则创建;
+// * 2. 本地没有但第三方App里有则删除第三方App里的。 +// * +// * @param ids +// * @return 成功返回true +// */ +// SyncInfoVo syncThirdAppDepartmentToLocal(String ids); +// +// /** +// * 将本地用户同步到第三方App
+// * 同步方向:本地 --> 第三方APP
+// * 同步逻辑:先判断是否同步过,有则修改、无则创建
+// * 注意:同步人员的状态,比如离职、禁用、逻辑删除等。 +// * (特殊点:1、目前逻辑特意做的不删除用户,防止企业微信提前上线,用户已经存在,但是平台无此用户。 +// * 企业微信支持禁用账号;钉钉不支持 +// * 2、企业微信里面是手机号激活,只能用户自己改,不允许通过接口改) +// * +// * @param ids +// * @return 成功返回空数组,失败返回错误信息 +// */ +// SyncInfoVo syncLocalUserToThirdApp(String ids); +// +// /** +// * 将第三方App用户同步到本地
+// * 同步方向:第三方APP --> 本地
+// * 同步逻辑:先判断是否同步过,有则修改、无则创建
+// * 注意:同步人员的状态,比如离职、禁用、逻辑删除等。 +// * +// * @return 成功返回空数组,失败返回错误信息 +// */ +// SyncInfoVo syncThirdAppUserToLocal(); +// +// /** +// * 根据本地用户ID,删除第三方APP的用户 +// * +// * @param userIdList 本地用户ID列表 +// * @return 0表示成功,其他值表示失败 +// */ +// int removeThirdAppUser(List userIdList); +// +// /** +// * 发送消息 +// * +// * @param message +// * @param verifyConfig 是否验证配置(未启用的APP会拒绝发送) +// * @return +// */ +// boolean sendMessage(MessageDTO message, boolean verifyConfig); +// +// /** +// * 发送消息 +// * +// * @param message +// * @return boolean +// */ +// boolean sendMessage(MessageDTO message); +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/DpUserServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/DpUserServiceImpl.java new file mode 100644 index 0000000..067196e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/DpUserServiceImpl.java @@ -0,0 +1,77 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.dynamic.datasource.annotation.DS; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.base.constant.CommonConstant; +import digital.bean.task.DpUser; +import digital.system.jeecg.system.mapper.DpUserMapper; +import digital.system.jeecg.system.service.IDpUserService; +import digital.util.util.PasswordUtil; +import digital.util.util.oConvertUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; + +/** + * @Description: dp_user + * @Author: jeecg-boot + * @Date: 2024-04-17 + * @Version: V1.0 + */ +@Slf4j +@Service +@DS("db_user_mysql") +public class DpUserServiceImpl extends ServiceImpl implements IDpUserService { + + @Autowired + private DpUserMapper dpUserMapper; + + + @Override + public DpUser getDeUserByName(String username) { + DpUser dpUser = dpUserMapper.selectOne(new QueryWrapper().lambda().eq(DpUser::getAccount, username)); + return dpUser; + } + + @Override + public DpUser getByUserId(String id) { + DpUser dpUser = dpUserMapper.selectById(id); + return dpUser; + } + + + @Override + public DpUser addUser(String mobile) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(DpUser::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(DpUser::getAccount, mobile); + DpUser dpUser = dpUserMapper.selectOne(queryWrapper); + if (dpUser == null) { + dpUser = new DpUser(); + dpUser.setAccount(mobile); + dpUser.setCreateTime(new Date());//设置创建时间 + String salt = oConvertUtils.randomGen(8); + dpUser.setSalt(salt); + String passwordEncode = PasswordUtil.encrypt(dpUser.getAccount(), "123456", salt); + dpUser.setPassword(passwordEncode); + dpUserMapper.insert(dpUser); + return dpUser; + } + return dpUser; + } + + + @Override + public DpUser getUserByAccount(String phone) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(DpUser::getDelFlag, CommonConstant.DEL_FLAG_0); + queryWrapper.lambda().eq(DpUser::getAccount, phone); + DpUser dpUser = dpUserMapper.selectOne(queryWrapper); + return dpUser; + } + + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/ImportFileServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/ImportFileServiceImpl.java new file mode 100644 index 0000000..8cbe236 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/ImportFileServiceImpl.java @@ -0,0 +1,28 @@ +package digital.system.jeecg.system.service.impl; + +import lombok.extern.slf4j.Slf4j; +import org.jeecgframework.poi.excel.imports.base.ImportFileServiceI; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import digital.util.util.CommonUtils; + +/** + * excel导入 实现类 + * + * @author: smcp + */ +@Slf4j +@Service +public class ImportFileServiceImpl implements ImportFileServiceI { + + @Value("${jeecg.path.upload}") + private String upLoadPath; + + @Value(value = "${jeecg.uploadType}") + private String uploadType; + + @Override + public String doUpload(byte[] data) { + return CommonUtils.uploadOnlineImage(data, upLoadPath, "import", uploadType); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementSendServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementSendServiceImpl.java new file mode 100644 index 0000000..656b838 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementSendServiceImpl.java @@ -0,0 +1,37 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysAnnouncementSend; +import digital.system.jeecg.system.mapper.SysAnnouncementSendMapper; +import digital.system.jeecg.system.model.AnnouncementSendModel; +import digital.system.jeecg.system.service.ISysAnnouncementSendService; + +import javax.annotation.Resource; +import java.util.List; + +/** + * @Description: 用户通告阅读标记表 + * @Author: zita + * @Date: 2019-02-21 + * @Version: V1.0 + */ +@Service +public class SysAnnouncementSendServiceImpl extends ServiceImpl implements ISysAnnouncementSendService { + + @Resource + private SysAnnouncementSendMapper sysAnnouncementSendMapper; + + @Override + public List queryByUserId(String userId) { + return sysAnnouncementSendMapper.queryByUserId(userId); + } + + @Override + public Page getMyAnnouncementSendPage(Page page, + AnnouncementSendModel announcementSendModel) { + return page.setRecords(sysAnnouncementSendMapper.getMyAnnouncementSendList(page, announcementSendModel)); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementServiceImpl.java new file mode 100644 index 0000000..1247037 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysAnnouncementServiceImpl.java @@ -0,0 +1,128 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.base.constant.CommonConstant; +import digital.system.jeecg.system.entity.SysAnnouncement; +import digital.system.jeecg.system.entity.SysAnnouncementSend; +import digital.system.jeecg.system.mapper.SysAnnouncementMapper; +import digital.system.jeecg.system.mapper.SysAnnouncementSendMapper; +import digital.system.jeecg.system.service.ISysAnnouncementService; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +/** + * @Description: 系统通告表 + * @Author: zita + * @Date: 2019-01-02 + * @Version: V1.0 + */ +@Service +public class SysAnnouncementServiceImpl extends ServiceImpl implements ISysAnnouncementService { + + @Resource + private SysAnnouncementMapper sysAnnouncementMapper; + + @Resource + private SysAnnouncementSendMapper sysAnnouncementSendMapper; + + @Transactional(rollbackFor = Exception.class) + @Override + public void saveAnnouncement(SysAnnouncement sysAnnouncement) { + if (sysAnnouncement.getMsgType().equals(CommonConstant.MSG_TYPE_ALL)) { + sysAnnouncementMapper.insert(sysAnnouncement); + } else { + // 1.插入通告表记录 + sysAnnouncementMapper.insert(sysAnnouncement); + // 2.插入用户通告阅读标记表记录 + String userId = sysAnnouncement.getUserIds(); + String[] userIds = userId.substring(0, (userId.length() - 1)).split(","); + String anntId = sysAnnouncement.getId(); + Date refDate = new Date(); + for (int i = 0; i < userIds.length; i++) { + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); + announcementSend.setUserId(userIds[i]); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + announcementSend.setReadTime(refDate); + sysAnnouncementSendMapper.insert(announcementSend); + } + } + } + + /** + * @功能:编辑消息信息 + */ + @Transactional(rollbackFor = Exception.class) + @Override + public boolean upDateAnnouncement(SysAnnouncement sysAnnouncement) { + // 1.更新系统信息表数据 + sysAnnouncementMapper.updateById(sysAnnouncement); + String userId = sysAnnouncement.getUserIds(); + if (oConvertUtils.isNotEmpty(userId) && sysAnnouncement.getMsgType().equals(CommonConstant.MSG_TYPE_UESR)) { + // 2.补充新的通知用户数据 + String[] userIds = userId.substring(0, (userId.length() - 1)).split(","); + String anntId = sysAnnouncement.getId(); + Date refDate = new Date(); + for (int i = 0; i < userIds.length; i++) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.eq(SysAnnouncementSend::getAnntId, anntId); + queryWrapper.eq(SysAnnouncementSend::getUserId, userIds[i]); + List announcementSends = sysAnnouncementSendMapper.selectList(queryWrapper); + if (announcementSends.size() <= 0) { + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); + announcementSend.setUserId(userIds[i]); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + announcementSend.setReadTime(refDate); + sysAnnouncementSendMapper.insert(announcementSend); + } + } + // 3. 删除多余通知用户数据 + Collection delUserIds = Arrays.asList(userIds); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.notIn(SysAnnouncementSend::getUserId, delUserIds); + queryWrapper.eq(SysAnnouncementSend::getAnntId, anntId); + sysAnnouncementSendMapper.delete(queryWrapper); + } + return true; + } + + /** + * 流程执行完成保存消息通知 + * + * @param title 标题 + * @param msgContent 信息内容 + */ + @Override + public void saveSysAnnouncement(String title, String msgContent) { + SysAnnouncement announcement = new SysAnnouncement(); + announcement.setTitile(title); + announcement.setMsgContent(msgContent); + announcement.setSender("JEECG BOOT"); + announcement.setPriority(CommonConstant.PRIORITY_L); + announcement.setMsgType(CommonConstant.MSG_TYPE_ALL); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + announcement.setDelFlag(CommonConstant.DEL_FLAG_0.toString()); + sysAnnouncementMapper.insert(announcement); + } + + @Override + public Page querySysCementPageByUserId(Page page, String userId, String msgCategory) { + if (page.getSize() == -1) { + return page.setRecords(sysAnnouncementMapper.querySysCementListByUserId(null, userId, msgCategory)); + } else { + return page.setRecords(sysAnnouncementMapper.querySysCementListByUserId(page, userId, msgCategory)); + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysBaseApiImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysBaseApiImpl.java new file mode 100644 index 0000000..6d202f2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysBaseApiImpl.java @@ -0,0 +1,1170 @@ +package digital.system.jeecg.system.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.google.common.base.Joiner; +import digital.base.constant.CacheConstant; +import digital.base.constant.CommonConstant; +import digital.base.constant.DataBaseConstant; +import digital.base.constant.WebsocketConst; +import digital.base.enums.UrlMatchEnum; +import digital.base.vo.LoginUser; +import digital.base.vo.SysPermissionDataRuleModel; +import digital.bean.jeecg.dto.OnlineAuthDTO; +import digital.bean.jeecg.dto.message.*; +import digital.bean.jeecg.vo.*; +import digital.bean.task.DpUser; +import digital.system.jeecg.group.base.ISysBaseAPI; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.message.entity.SysMessageTemplate; +import digital.system.jeecg.message.service.ISysMessageTemplateService; +import digital.system.jeecg.system.entity.*; +import digital.system.jeecg.system.mapper.*; +import digital.system.jeecg.system.service.*; +import digital.system.jeecg.system.util.SecurityUtil; +import digital.util.exception.JeecgBootException; +import digital.util.util.*; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.util.AntPathMatcher; +import org.springframework.util.PathMatcher; + +import javax.annotation.Resource; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.DatabaseMetaData; +import java.sql.SQLException; +import java.util.*; + +/** + * @Description: 底层共通业务API,提供其他独立模块调用 + * @Author: scott + * @Date:2019-4-20 + * @Version:V1.0 + */ +@Slf4j +@Service +public class SysBaseApiImpl implements ISysBaseAPI { + /** + * 当前系统数据库类型 + */ + private static String DB_TYPE = ""; + + @Autowired + private IDpUserService dpUserService; + @Autowired + ISysCategoryService sysCategoryService; + @Autowired + private ISysMessageTemplateService sysMessageTemplateService; + @Resource + private SysUserMapper userMapper; + @Resource + private SysUserRoleMapper sysUserRoleMapper; + @Autowired + private ISysDepartService sysDepartService; + @Autowired + private ISysDictService sysDictService; + @Resource + private SysAnnouncementMapper sysAnnouncementMapper; + @Resource + private SysAnnouncementSendMapper sysAnnouncementSendMapper; + @Resource + private SysRoleMapper roleMapper; + @Resource + private SysDepartMapper departMapper; + @Resource + private SysCategoryMapper categoryMapper; + @Autowired + private ISysDataSourceService dataSourceService; + @Autowired + private ISysUserDepartService sysUserDepartService; + @Resource + private SysPermissionMapper sysPermissionMapper; + @Autowired + private ISysPermissionDataRuleService sysPermissionDataRuleService; + + @Override +// @Cacheable(cacheNames = CacheConstant.SYS_USERS_CACHE, key = "#username") + public LoginUser getUserByName(String username) { + log.debug(username + "====================getUserByName======================"); + if (oConvertUtils.isEmpty(username)) { + return null; + } + LoginUser loginUser = new LoginUser(); + DpUser sysUser = dpUserService.getDeUserByName(username); + if (sysUser == null) { + DpUser dpUser = dpUserService.addUser(username); + BeanUtils.copyProperties(dpUser, loginUser); + loginUser.setUsername(dpUser.getAccount()); + return loginUser; + } + BeanUtils.copyProperties(sysUser, loginUser); + loginUser.setUsername(sysUser.getAccount()); + //查询用户角色 + return loginUser; + } + + @Override + public String translateDictFromTable(String table, String text, String code, String key) { + return sysDictService.queryTableDictTextByKey(table, text, code, key); + } + + @Override + public String translateDict(String code, String key) { + return sysDictService.queryDictTextByKey(code, key); + } + + @Override + public List queryPermissionDataRule(String component, String requestPath, String username) { + List currentSyspermission = null; + if (oConvertUtils.isNotEmpty(component)) { + //1.通过注解属性pageComponent 获取菜单 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysPermission::getDelFlag, 0); + query.eq(SysPermission::getComponent, component); + currentSyspermission = sysPermissionMapper.selectList(query); + } else { + //1.直接通过前端请求地址查询菜单 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysPermission::getMenuType, 2); + query.eq(SysPermission::getDelFlag, 0); + query.eq(SysPermission::getUrl, requestPath); + currentSyspermission = sysPermissionMapper.selectList(query); + //2.未找到 再通过自定义匹配URL 获取菜单 + if (currentSyspermission == null || currentSyspermission.size() == 0) { + //通过自定义URL匹配规则 获取菜单(实现通过菜单配置数据权限规则,实际上针对获取数据接口进行数据规则控制) + String userMatchUrl = UrlMatchEnum.getMatchResultByUrl(requestPath); + LambdaQueryWrapper queryQserMatch = new LambdaQueryWrapper(); + // update-begin-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1 + //queryQserMatch.eq(SysPermission::getMenuType, 1); + // update-end-author:taoyan date:20211027 for: online菜单如果配置成一级菜单 权限查询不到 取消menuType = 1 + queryQserMatch.eq(SysPermission::getDelFlag, 0); + queryQserMatch.eq(SysPermission::getUrl, userMatchUrl); + if (oConvertUtils.isNotEmpty(userMatchUrl)) { + currentSyspermission = sysPermissionMapper.selectList(queryQserMatch); + } + } + //3.未找到 再通过正则匹配获取菜单 + if (currentSyspermission == null || currentSyspermission.size() == 0) { + //通过正则匹配权限配置 + String regUrl = getRegexpUrl(requestPath); + if (regUrl != null) { + currentSyspermission = sysPermissionMapper.selectList(new LambdaQueryWrapper().eq(SysPermission::getMenuType, 2).eq(SysPermission::getUrl, regUrl).eq(SysPermission::getDelFlag, 0)); + } + } + } + if (currentSyspermission != null && currentSyspermission.size() > 0) { + List dataRules = new ArrayList(); + for (SysPermission sysPermission : currentSyspermission) { + // update-begin--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722 + List temp = sysPermissionDataRuleService.queryPermissionDataRules(username, sysPermission.getId()); + if (temp != null && temp.size() > 0) { + //dataRules.addAll(temp); + dataRules = oConvertUtils.entityListToModelList(temp, SysPermissionDataRuleModel.class); + } + // update-end--Author:scott Date:20191119 for:数据权限规则编码不规范,项目存在相同包名和类名 #722 + } + return dataRules; + } + return null; + } + + /** + * 匹配前端传过来的地址 匹配成功返回正则地址 + * AntPathMatcher匹配地址 + * ()* 匹配0个或多个字符 + * ()**匹配0个或多个目录 + */ + private String getRegexpUrl(String url) { + List list = sysPermissionMapper.queryPermissionUrlWithStar(); + if (list != null && list.size() > 0) { + for (String p : list) { + PathMatcher matcher = new AntPathMatcher(); + if (matcher.match(p, url)) { + return p; + } + } + } + return null; + } + + @Override + public SysUserCacheInfo getCacheUser(String username) { + SysUserCacheInfo info = new SysUserCacheInfo(); + info.setOneDepart(true); + LoginUser user = this.getUserByName(username); + if (user != null) { + info.setSysUserCode(user.getUsername()); + info.setSysUserName(user.getRealname()); +// info.setSysOrgCode(user.getOrgCode()); + } else { + return null; + } + //多部门支持in查询 + List list = departMapper.queryUserDeparts(user.getId()); + List sysMultiOrgCode = new ArrayList(); + if (list == null || list.size() == 0) { + //当前用户无部门 + //sysMultiOrgCode.add("0"); + } else if (list.size() == 1) { + sysMultiOrgCode.add(list.get(0).getOrgCode()); + } else { + info.setOneDepart(false); + for (SysDepart dpt : list) { + sysMultiOrgCode.add(dpt.getOrgCode()); + } + } + info.setSysMultiOrgCode(sysMultiOrgCode); + return info; + } + + @Override + public LoginUser getUserById(String id) { + if (oConvertUtils.isEmpty(id)) { + return null; + } + LoginUser loginUser = new LoginUser(); + SysUser sysUser = userMapper.selectById(id); + if (sysUser == null) { + return null; + } + BeanUtils.copyProperties(sysUser, loginUser); + return loginUser; + } + + @Override + public List getRolesByUsername(String username) { + return sysUserRoleMapper.getRoleByUserName(username); + } + + @Override + public List getDepartIdsByUsername(String username) { + List list = sysDepartService.queryDepartsByUsername(username); + List result = new ArrayList<>(list.size()); + for (SysDepart depart : list) { + result.add(depart.getId()); + } + return result; + } + + @Override + public List getDepartNamesByUsername(String username) { + List list = sysDepartService.queryDepartsByUsername(username); + List result = new ArrayList<>(list.size()); + for (SysDepart depart : list) { + result.add(depart.getDepartName()); + } + return result; + } + + @Override + public DictModel getParentDepartId(String departId) { + SysDepart depart = departMapper.getParentDepartId(departId); + DictModel model = new DictModel(depart.getId(), depart.getParentId()); + return model; + } + + @Override + @Cacheable(value = CacheConstant.SYS_DICT_CACHE, key = "#code", unless = "#result == null ") + public List queryDictItemsByCode(String code) { + return sysDictService.queryDictItemsByCode(code); + } + + @Override + @Cacheable(value = CacheConstant.SYS_ENABLE_DICT_CACHE, key = "#code", unless = "#result == null ") + public List queryEnableDictItemsByCode(String code) { + return sysDictService.queryEnableDictItemsByCode(code); + } + + @Override + public List queryTableDictItemsByCode(String table, String text, String code) { + //update-begin-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799 + if (table.indexOf("#{") >= 0) { + table = QueryGenerator.getSqlRuleValue(table); + } + //update-end-author:taoyan date:20200820 for:【Online+系统】字典表加权限控制机制逻辑,想法不错 LOWCOD-799 + return sysDictService.queryTableDictItemsByCode(table, text, code); + } + + @Override + public List queryAllDepartBackDictModel() { + return sysDictService.queryAllDepartBackDictModel(); + } + + @Override + public void sendSysAnnouncement(MessageDTO message) { + this.sendSysAnnouncement(message.getFromUser(), + message.getToUser(), + message.getTitle(), + message.getContent(), + message.getCategory()); + try { + // 同步发送第三方APP消息 +// wechatEnterpriseService.sendMessage(message, true); +// dingtalkService.sendMessage(message, true); + } catch (Exception e) { + log.error("同步发送第三方APP消息失败!", e); + } + } + + @Override + public void sendBusAnnouncement(BusMessageDTO message) { + sendBusAnnouncement(message.getFromUser(), + message.getToUser(), + message.getTitle(), + message.getContent(), + message.getCategory(), + message.getBusType(), + message.getBusId()); + try { + // 同步发送第三方APP消息 +// wechatEnterpriseService.sendMessage(message, true); +// dingtalkService.sendMessage(message, true); + } catch (Exception e) { + log.error("同步发送第三方APP消息失败!", e); + } + } + + @Override + public void sendTemplateAnnouncement(TemplateMessageDTO message) { + String templateCode = message.getTemplateCode(); + String title = message.getTitle(); + Map map = message.getTemplateParam(); + String fromUser = message.getFromUser(); + String toUser = message.getToUser(); + + List sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode); + if (sysSmsTemplates == null || sysSmsTemplates.size() == 0) { + throw new JeecgBootException("消息模板不存在,模板编码:" + templateCode); + } + SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0); + //模板标题 + title = title == null ? sysSmsTemplate.getTemplateName() : title; + //模板内容 + String content = sysSmsTemplate.getTemplateContent(); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String str = "${" + entry.getKey() + "}"; + if (oConvertUtils.isNotEmpty(title)) { + title = title.replace(str, entry.getValue()); + } + content = content.replace(str, entry.getValue()); + } + } + + SysAnnouncement announcement = new SysAnnouncement(); + announcement.setTitile(title); + announcement.setMsgContent(content); + announcement.setSender(fromUser); + announcement.setPriority(CommonConstant.PRIORITY_M); + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2); + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + sysAnnouncementMapper.insert(announcement); + // 2.插入用户通告阅读标记表记录 + String userId = toUser; + String[] userIds = userId.split(","); + String anntId = announcement.getId(); + for (int i = 0; i < userIds.length; i++) { + if (oConvertUtils.isNotEmpty(userIds[i])) { + SysUser sysUser = userMapper.getUserByName(userIds[i]); + if (sysUser == null) { + continue; + } + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); +// announcementSend.setUserId(sysUser.getId()); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + sysAnnouncementSendMapper.insert(announcementSend); +// JSONObject obj = new JSONObject(); +// obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); +// obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId()); +// obj.put(WebsocketConst.MSG_ID, announcement.getId()); +// obj.put(WebsocketConst.MSG_TXT, announcement.getTitile()); +// webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); + } + } + try { + // 同步企业微信、钉钉的消息通知 +// dingtalkService.sendActionCardMessage(announcement, true); +// wechatEnterpriseService.sendTextCardMessage(announcement, true); + } catch (Exception e) { + log.error("同步发送第三方APP消息失败!", e); + } + + } + + @Override + public void sendBusTemplateAnnouncement(BusTemplateMessageDTO message) { + String templateCode = message.getTemplateCode(); + String title = message.getTitle(); + Map map = message.getTemplateParam(); + String fromUser = message.getFromUser(); + String toUser = message.getToUser(); + String busId = message.getBusId(); + String busType = message.getBusType(); + + List sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode); + if (sysSmsTemplates == null || sysSmsTemplates.size() == 0) { + throw new JeecgBootException("消息模板不存在,模板编码:" + templateCode); + } + SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0); + //模板标题 + title = title == null ? sysSmsTemplate.getTemplateName() : title; + //模板内容 + String content = sysSmsTemplate.getTemplateContent(); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String str = "${" + entry.getKey() + "}"; + title = title.replace(str, entry.getValue()); + content = content.replace(str, entry.getValue()); + } + } + SysAnnouncement announcement = new SysAnnouncement(); + announcement.setTitile(title); + announcement.setMsgContent(content); + announcement.setSender(fromUser); + announcement.setPriority(CommonConstant.PRIORITY_M); + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + announcement.setMsgCategory(CommonConstant.MSG_CATEGORY_2); + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + announcement.setBusId(busId); + announcement.setBusType(busType); + announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType()); + announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage()); + sysAnnouncementMapper.insert(announcement); + // 2.插入用户通告阅读标记表记录 + String userId = toUser; + String[] userIds = userId.split(","); + String anntId = announcement.getId(); + for (int i = 0; i < userIds.length; i++) { + if (oConvertUtils.isNotEmpty(userIds[i])) { +// SysUser sysUser = userMapper.getUserByName(userIds[i]); +// if (sysUser == null) { +// continue; +// } +// SysAnnouncementSend announcementSend = new SysAnnouncementSend(); +// announcementSend.setAnntId(anntId); +// announcementSend.setUserId(sysUser.getId()); +// announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); +// sysAnnouncementSendMapper.insert(announcementSend); +// JSONObject obj = new JSONObject(); +// obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); +// obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId()); +// obj.put(WebsocketConst.MSG_ID, announcement.getId()); +// obj.put(WebsocketConst.MSG_TXT, announcement.getTitile()); +// webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); + } + } + try { + // 同步企业微信、钉钉的消息通知 +// dingtalkService.sendActionCardMessage(announcement, true); +// wechatEnterpriseService.sendTextCardMessage(announcement, true); + } catch (Exception e) { + log.error("同步发送第三方APP消息失败!", e); + } + + } + + @Override + public String parseTemplateByCode(TemplateDTO templateDTO) { + String templateCode = templateDTO.getTemplateCode(); + Map map = templateDTO.getTemplateParam(); + List sysSmsTemplates = sysMessageTemplateService.selectByCode(templateCode); + if (sysSmsTemplates == null || sysSmsTemplates.size() == 0) { + throw new JeecgBootException("消息模板不存在,模板编码:" + templateCode); + } + SysMessageTemplate sysSmsTemplate = sysSmsTemplates.get(0); + //模板内容 + String content = sysSmsTemplate.getTemplateContent(); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String str = "${" + entry.getKey() + "}"; + content = content.replace(str, entry.getValue()); + } + } + return content; + } + + @Override + public void updateSysAnnounReadFlag(String busType, String busId) { + SysAnnouncement announcement = sysAnnouncementMapper.selectOne(new QueryWrapper().eq("bus_type", busType).eq("bus_id", busId)); + if (announcement != null) { + LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// String userId = sysUser.getId(); + LambdaUpdateWrapper updateWrapper = new UpdateWrapper().lambda(); + updateWrapper.set(SysAnnouncementSend::getReadFlag, CommonConstant.HAS_READ_FLAG); + updateWrapper.set(SysAnnouncementSend::getReadTime, new Date()); +// updateWrapper.last("where annt_id ='" + announcement.getId() + "' and user_id ='" + userId + "'"); + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + sysAnnouncementSendMapper.update(announcementSend, updateWrapper); + } + } + + /** + * 获取数据库类型 + * + * @param dataSource + * @return + * @throws SQLException + */ + private String getDatabaseTypeByDataSource(DataSource dataSource) throws SQLException { + if ("".equals(DB_TYPE)) { + Connection connection = dataSource.getConnection(); + try { + DatabaseMetaData md = connection.getMetaData(); + String dbType = md.getDatabaseProductName().toLowerCase(); + if (dbType.indexOf("mysql") >= 0) { + DB_TYPE = DataBaseConstant.DB_TYPE_MYSQL; + } else if (dbType.indexOf("oracle") >= 0) { + DB_TYPE = DataBaseConstant.DB_TYPE_ORACLE; + } else if (dbType.indexOf("sqlserver") >= 0 || dbType.indexOf("sql server") >= 0) { + DB_TYPE = DataBaseConstant.DB_TYPE_SQLSERVER; + } else if (dbType.indexOf("postgresql") >= 0) { + DB_TYPE = DataBaseConstant.DB_TYPE_POSTGRESQL; + } else if (dbType.indexOf("mariadb") >= 0) { + DB_TYPE = DataBaseConstant.DB_TYPE_MARIADB; + } else { + log.error("数据库类型:[" + dbType + "]不识别!"); + //throw new JeecgBootException("数据库类型:["+dbType+"]不识别!"); + } + } catch (Exception e) { + log.error(e.getMessage(), e); + } finally { + connection.close(); + } + } + return DB_TYPE; + + } + + @Override + public List queryAllDict() { + // 查询并排序 + QueryWrapper queryWrapper = new QueryWrapper(); + queryWrapper.orderByAsc("create_time"); + List dicts = sysDictService.list(queryWrapper); + // 封装成 model + List list = new ArrayList(); + for (SysDict dict : dicts) { + list.add(new DictModel(dict.getDictCode(), dict.getDictName())); + } + + return list; + } + + @Override + public List queryAllSysCategory() { + List ls = categoryMapper.selectList(null); + List res = oConvertUtils.entityListToModelList(ls, SysCategoryModel.class); + return res; + } + + @Override + public List queryFilterTableDictInfo(String table, String text, String code, String filterSql) { + return sysDictService.queryTableDictItemsByCodeAndFilter(table, text, code, filterSql); + } + + @Override + public List queryTableDictByKeys(String table, String text, String code, String[] keyArray) { + return sysDictService.queryTableDictByKeys(table, text, code, Joiner.on(",").join(keyArray)); + } + + @Override + public List queryAllUserBackCombo() { + List list = new ArrayList(); + List userList = userMapper.selectList(new QueryWrapper().eq("status", 1).eq("del_flag", 0)); + for (SysUser user : userList) { + ComboModel model = new ComboModel(); + model.setTitle(user.getRealname()); +// model.setId(user.getId()); + model.setUsername(user.getUsername()); + list.add(model); + } + return list; + } + + @Override + public JSONObject queryAllUser(String userIds, Integer pageNo, Integer pageSize) { + JSONObject json = new JSONObject(); + QueryWrapper queryWrapper = new QueryWrapper().eq("status", 1).eq("del_flag", 0); + List list = new ArrayList(); + Page page = new Page(pageNo, pageSize); + IPage pageList = userMapper.selectPage(page, queryWrapper); + for (SysUser user : pageList.getRecords()) { + ComboModel model = new ComboModel(); + model.setUsername(user.getUsername()); + model.setTitle(user.getRealname()); +// model.setId(user.getId()); + model.setEmail(user.getEmail()); + if (oConvertUtils.isNotEmpty(userIds)) { + String[] temp = userIds.split(","); + for (int i = 0; i < temp.length; i++) { + if (temp[i].equals(user.getId())) { + model.setChecked(true); + } + } + } + list.add(model); + } + json.put("list", list); + json.put("total", pageList.getTotal()); + return json; + } + + @Override + public List queryAllRole() { + List list = new ArrayList(); + List roleList = roleMapper.selectList(new QueryWrapper()); + for (SysRole role : roleList) { + ComboModel model = new ComboModel(); + model.setTitle(role.getRoleName()); + model.setId(role.getId()); + list.add(model); + } + return list; + } + + @Override + public List queryAllRole(String[] roleIds) { + List list = new ArrayList(); + List roleList = roleMapper.selectList(new QueryWrapper()); + for (SysRole role : roleList) { + ComboModel model = new ComboModel(); + model.setTitle(role.getRoleName()); + model.setId(role.getId()); + model.setRoleCode(role.getRoleCode()); + if (oConvertUtils.isNotEmpty(roleIds)) { + for (int i = 0; i < roleIds.length; i++) { + if (roleIds[i].equals(role.getId())) { + model.setChecked(true); + } + } + } + list.add(model); + } + return list; + } + + @Override + public List getRoleIdsByUsername(String username) { + return sysUserRoleMapper.getRoleIdByUserName(username); + } + + @Override + public String getDepartIdsByOrgCode(String orgCode) { + return departMapper.queryDepartIdByOrgCode(orgCode); + } + + @Override + public List getAllSysDepart() { + List departModelList = new ArrayList(); + List departList = departMapper.selectList(new QueryWrapper().eq("del_flag", "0")); + for (SysDepart depart : departList) { + SysDepartModel model = new SysDepartModel(); + BeanUtils.copyProperties(depart, model); + departModelList.add(model); + } + return departModelList; + } + + @Override + public DynamicDataSourceModel getDynamicDbSourceById(String dbSourceId) { + SysDataSource dbSource = dataSourceService.getById(dbSourceId); + if (dbSource != null && StringUtils.isNotBlank(dbSource.getDbPassword())) { + String dbPassword = dbSource.getDbPassword(); + String decodedStr = SecurityUtil.jiemi(dbPassword); + dbSource.setDbPassword(decodedStr); + } + return new DynamicDataSourceModel(dbSource); + } + + @Override + public DynamicDataSourceModel getDynamicDbSourceByCode(String dbSourceCode) { + SysDataSource dbSource = dataSourceService.getOne(new LambdaQueryWrapper().eq(SysDataSource::getCode, dbSourceCode)); + if (dbSource != null && StringUtils.isNotBlank(dbSource.getDbPassword())) { + String dbPassword = dbSource.getDbPassword(); + String decodedStr = SecurityUtil.jiemi(dbPassword); + dbSource.setDbPassword(decodedStr); + } + return new DynamicDataSourceModel(dbSource); + } + + @Override + public List getDeptHeadByDepId(String deptId) { + List userList = userMapper.selectList(new QueryWrapper().like("depart_ids", deptId).eq("status", 1).eq("del_flag", 0)); + List list = new ArrayList<>(); + for (SysUser user : userList) { + list.add(user.getUsername()); + } + return list; + } + + @Override + public void sendWebSocketMsg(String[] userIds, String cmd) { + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, cmd); +// webSocket.sendMessage(userIds, obj.toJSONString()); + } + + @Override + public List queryAllUserByIds(String[] userIds) { + QueryWrapper queryWrapper = new QueryWrapper().eq("status", 1).eq("del_flag", 0); + queryWrapper.in("id", userIds); + List loginUsers = new ArrayList<>(); + List sysUsers = userMapper.selectList(queryWrapper); + for (SysUser user : sysUsers) { + LoginUser loginUser = new LoginUser(); + BeanUtils.copyProperties(user, loginUser); + loginUsers.add(loginUser); + } + return loginUsers; + } + + /** + * 推送签到人员信息 + * + * @param userId + */ + @Override + public void meetingSignWebsocket(String userId) { + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_SIGN); + obj.put(WebsocketConst.MSG_USER_ID, userId); + //TODO 目前全部推送,后面修改 +// webSocket.sendMessage(obj.toJSONString()); + } + + @Override + public List queryUserByNames(String[] userNames) { + QueryWrapper queryWrapper = new QueryWrapper().eq("status", 1).eq("del_flag", 0); + queryWrapper.in("username", userNames); + List loginUsers = new ArrayList<>(); + List sysUsers = userMapper.selectList(queryWrapper); + for (SysUser user : sysUsers) { + LoginUser loginUser = new LoginUser(); + BeanUtils.copyProperties(user, loginUser); + loginUsers.add(loginUser); + } + return loginUsers; + } + + @Override + public SysDepartModel selectAllById(String id) { + SysDepart sysDepart = sysDepartService.getById(id); + SysDepartModel sysDepartModel = new SysDepartModel(); + BeanUtils.copyProperties(sysDepart, sysDepartModel); + return sysDepartModel; + } + + @Override + public List queryDeptUsersByUserId(String userId) { + List userIds = new ArrayList<>(); + List userDepartList = sysUserDepartService.list(new QueryWrapper().eq("user_id", userId)); + if (userDepartList != null) { + //查找所属公司 + String orgCodes = ""; + for (SysUserDepart userDepart : userDepartList) { + //查询所属公司编码 + SysDepart depart = sysDepartService.getById(userDepart.getDepId()); + int length = YouBianCodeUtil.ZHANWEI_LENGTH; + String compyOrgCode = ""; + if (depart != null && depart.getOrgCode() != null) { + compyOrgCode = depart.getOrgCode().substring(0, length); + if (orgCodes.indexOf(compyOrgCode) == -1) { + orgCodes = orgCodes + "," + compyOrgCode; + } + } + } + if (oConvertUtils.isNotEmpty(orgCodes)) { + orgCodes = orgCodes.substring(1); + List listIds = departMapper.getSubDepIdsByOrgCodes(orgCodes.split(",")); + List userList = sysUserDepartService.list(new QueryWrapper().in("dep_id", listIds)); + for (SysUserDepart userDepart : userList) { + if (!userIds.contains(userDepart.getUserId())) { + userIds.add(userDepart.getUserId()); + } + } + } + } + return userIds; + } + + /** + * 查询用户拥有的角色集合 + * + * @param username + * @return + */ + @Override + public Set getUserRoleSet(String username) { + // 查询用户拥有的角色集合 + List roles = sysUserRoleMapper.getRoleByUserName(username); + log.info("-------通过数据库读取用户拥有的角色Rules------username: " + username + ",Roles size: " + (roles == null ? 0 : roles.size())); + return new HashSet<>(roles); + } + + /** + * 查询用户拥有的权限集合 + * + * @param username + * @return + */ + @Override + public Set getUserPermissionSet(String username) { + Set permissionSet = new HashSet<>(); + List permissionList = sysPermissionMapper.queryByUser(username); + for (SysPermission po : permissionList) { +// // TODO URL规则有问题? +// if (oConvertUtils.isNotEmpty(po.getUrl())) { +// permissionSet.add(po.getUrl()); +// } + if (oConvertUtils.isNotEmpty(po.getPerms())) { + permissionSet.add(po.getPerms()); + } + } + log.info("-------通过数据库读取用户拥有的权限Perms------username: " + username + ",Perms size: " + (permissionSet == null ? 0 : permissionSet.size())); + return permissionSet; + } + + /** + * 判断online菜单是否有权限 + * + * @param onlineAuthDTO + * @return + */ + @Override + public boolean hasOnlineAuth(OnlineAuthDTO onlineAuthDTO) { + String username = onlineAuthDTO.getUsername(); + List possibleUrl = onlineAuthDTO.getPossibleUrl(); + String onlineFormUrl = onlineAuthDTO.getOnlineFormUrl(); + //查询菜单 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysPermission::getDelFlag, 0); + query.in(SysPermission::getUrl, possibleUrl); + List permissionList = sysPermissionMapper.selectList(query); + if (permissionList == null || permissionList.size() == 0) { + //没有配置菜单 找online表单菜单地址 + SysPermission sysPermission = new SysPermission(); + sysPermission.setUrl(onlineFormUrl); + int count = sysPermissionMapper.queryCountByUsername(username, sysPermission); + if (count <= 0) { + return false; + } + } else { + //找到菜单了 + boolean has = false; + for (SysPermission p : permissionList) { + int count = sysPermissionMapper.queryCountByUsername(username, p); + has = has || (count > 0); + } + return has; + } + return true; + } + + /** + * 查询用户拥有的角色集合 common api 里面的接口实现 + * + * @param username + * @return + */ + @Override + public Set queryUserRoles(String username) { + return getUserRoleSet(username); + } + + /** + * 查询用户拥有的权限集合 common api 里面的接口实现 + * + * @param username + * @return + */ + @Override + public Set queryUserAuths(String username) { + return getUserPermissionSet(username); + } + + /** + * 36根据多个用户账号(逗号分隔),查询返回多个用户信息 + * + * @param usernames + * @return + */ + @Override + public List queryUsersByUsernames(String usernames) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysUser::getUsername, usernames.split(",")); + return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class); + } + + @Override + public List queryUsersByIds(String ids) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysUser::getId, ids.split(",")); + return JSON.parseArray(JSON.toJSONString(userMapper.selectList(queryWrapper))).toJavaList(JSONObject.class); + } + + /** + * 37根据多个部门编码(逗号分隔),查询返回多个部门信息 + * + * @param orgCodes + * @return + */ + @Override + public List queryDepartsByOrgcodes(String orgCodes) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysDepart::getOrgCode, orgCodes.split(",")); + return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class); + } + + @Override + public List queryDepartsByIds(String ids) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysDepart::getId, ids.split(",")); + return JSON.parseArray(JSON.toJSONString(sysDepartService.list(queryWrapper))).toJavaList(JSONObject.class); + } + + /** + * 发消息 + * + * @param fromUser + * @param toUser + * @param title + * @param msgContent + * @param setMsgCategory + */ + private void sendSysAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory) { + SysAnnouncement announcement = new SysAnnouncement(); + announcement.setTitile(title); + announcement.setMsgContent(msgContent); + announcement.setSender(fromUser); + announcement.setPriority(CommonConstant.PRIORITY_M); + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + announcement.setMsgCategory(setMsgCategory); + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + sysAnnouncementMapper.insert(announcement); + // 2.插入用户通告阅读标记表记录 + String userId = toUser; + String[] userIds = userId.split(","); + String anntId = announcement.getId(); + for (int i = 0; i < userIds.length; i++) { + if (oConvertUtils.isNotEmpty(userIds[i])) { + SysUser sysUser = userMapper.getUserByName(userIds[i]); + if (sysUser == null) { + continue; + } + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); +// announcementSend.setUserId(sysUser.getId()); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + sysAnnouncementSendMapper.insert(announcementSend); + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); +// obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId()); + obj.put(WebsocketConst.MSG_ID, announcement.getId()); + obj.put(WebsocketConst.MSG_TXT, announcement.getTitile()); +// webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); + } + } + + } + + /** + * 发消息 带业务参数 + * + * @param fromUser + * @param toUser + * @param title + * @param msgContent + * @param setMsgCategory + * @param busType + * @param busId + */ + private void sendBusAnnouncement(String fromUser, String toUser, String title, String msgContent, String setMsgCategory, String busType, String busId) { + SysAnnouncement announcement = new SysAnnouncement(); + announcement.setTitile(title); + announcement.setMsgContent(msgContent); + announcement.setSender(fromUser); + announcement.setPriority(CommonConstant.PRIORITY_M); + announcement.setMsgType(CommonConstant.MSG_TYPE_UESR); + announcement.setSendStatus(CommonConstant.HAS_SEND); + announcement.setSendTime(new Date()); + announcement.setMsgCategory(setMsgCategory); + announcement.setDelFlag(String.valueOf(CommonConstant.DEL_FLAG_0)); + announcement.setBusId(busId); + announcement.setBusType(busType); + announcement.setOpenType(SysAnnmentTypeEnum.getByType(busType).getOpenType()); + announcement.setOpenPage(SysAnnmentTypeEnum.getByType(busType).getOpenPage()); + sysAnnouncementMapper.insert(announcement); + // 2.插入用户通告阅读标记表记录 + String userId = toUser; + String[] userIds = userId.split(","); + String anntId = announcement.getId(); + for (int i = 0; i < userIds.length; i++) { + if (oConvertUtils.isNotEmpty(userIds[i])) { + SysUser sysUser = userMapper.getUserByName(userIds[i]); + if (sysUser == null) { + continue; + } + SysAnnouncementSend announcementSend = new SysAnnouncementSend(); + announcementSend.setAnntId(anntId); +// announcementSend.setUserId(sysUser.getId()); + announcementSend.setReadFlag(CommonConstant.NO_READ_FLAG); + sysAnnouncementSendMapper.insert(announcementSend); + JSONObject obj = new JSONObject(); + obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER); +// obj.put(WebsocketConst.MSG_USER_ID, sysUser.getId()); + obj.put(WebsocketConst.MSG_ID, announcement.getId()); + obj.put(WebsocketConst.MSG_TXT, announcement.getTitile()); +// webSocket.sendMessage(sysUser.getId(), obj.toJSONString()); + } + } + } + + /** + * 发送邮件消息 + * + * @param email + * @param title + * @param content + */ +// @Override +// public void sendEmailMsg(String email, String title, String content) { +// EmailSendMsgHandle emailHandle = new EmailSendMsgHandle(); +// emailHandle.SendMsg(email, title, content); +// } + + /** + * 获取公司下级部门和所有用户id信息 + * + * @param orgCode + * @return + */ + @Override + public List getDeptUserByOrgCode(String orgCode) { + //1.获取公司信息 + SysDepart comp = sysDepartService.queryCompByOrgCode(orgCode); + if (comp != null) { + //2.获取公司下级部门 + List departs = sysDepartService.queryDeptByPid(comp.getId()); + //3.获取部门下的人员信息 + List list = new ArrayList(); + //4.处理部门和下级用户数据 + for (SysDepart dept : departs) { + Map map = new HashMap(5); + //部门名称 + String departName = dept.getDepartName(); + //根据部门编码获取下级部门id + List listIds = departMapper.getSubDepIdsByDepId(dept.getId()); + //根据下级部门ids获取下级部门的所有用户 + List userList = sysUserDepartService.list(new QueryWrapper().in("dep_id", listIds)); + List userIds = new ArrayList<>(); + for (SysUserDepart userDepart : userList) { + if (!userIds.contains(userDepart.getUserId())) { + userIds.add(userDepart.getUserId()); + } + } + map.put("name", departName); + map.put("ids", userIds); + list.add(map); + } + return list; + } + return null; + } + + /** + * 查询分类字典翻译 + * + * @param ids 分类字典表id + * @return + */ + @Override + public List loadCategoryDictItem(String ids) { + return sysCategoryService.loadDictItem(ids, false); + } + + /** + * 根据字典code加载字典text + * + * @param dictCode 顺序:tableName,text,code + * @param keys 要查询的key + * @return + */ + @Override + public List loadDictItem(String dictCode, String keys) { + String[] params = dictCode.split(","); + return sysDictService.queryTableDictByKeys(params[0], params[1], params[2], keys, false); + } + + /** + * 根据字典code查询字典项 + * + * @param dictCode 顺序:tableName,text,code + * @param dictCode 要查询的key + * @return + */ + @Override + public List getDictItems(String dictCode) { + List ls = sysDictService.getDictItems(dictCode); + if (ls == null) { + ls = new ArrayList<>(); + } + return ls; + } + + /** + * 根据多个字典code查询多个字典项 + * + * @param dictCodeList + * @return key = dictCode ; value=对应的字典项 + */ + @Override + public Map> getManyDictItems(List dictCodeList) { + return sysDictService.queryDictItemsByCodeList(dictCodeList); + } + + /** + * 【下拉搜索】 + * 大数据量的字典表 走异步加载,即前端输入内容过滤数据 + * + * @param dictCode 字典code格式:table,text,code + * @param keyword 过滤关键字 + * @return + */ + @Override + public List loadDictItemByKeyword(String dictCode, String keyword, Integer pageSize) { + return sysDictService.loadDict(dictCode, keyword, pageSize); + } + + @Override + public Map> translateManyDict(String dictCodes, String keys) { + List dictCodeList = Arrays.asList(dictCodes.split(",")); + List values = Arrays.asList(keys.split(",")); + return sysDictService.queryManyDictByKeys(dictCodeList, values); + } + + @Override + public List translateDictFromTableByKeys(String table, String text, String code, String keys) { + return sysDictService.queryTableDictTextByKeys(table, text, code, Arrays.asList(keys.split(","))); + } + +} \ No newline at end of file diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCategoryServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCategoryServiceImpl.java new file mode 100644 index 0000000..96fc653 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCategoryServiceImpl.java @@ -0,0 +1,238 @@ +package digital.system.jeecg.system.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.base.constant.FillRuleConstant; +import digital.system.jeecg.system.entity.SysCategory; +import digital.system.jeecg.system.mapper.SysCategoryMapper; +import digital.system.jeecg.system.model.TreeSelectModel; +import digital.system.jeecg.system.service.ISysCategoryService; +import digital.util.exception.JeecgBootException; +import digital.util.util.FillRuleUtil; +import digital.util.util.oConvertUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Description: 分类字典 + * @Author: zita + * @Date: 2019-05-29 + * @Version: V1.0 + */ +@Service +public class SysCategoryServiceImpl extends ServiceImpl implements ISysCategoryService { + + @Override + public void addSysCategory(SysCategory sysCategory) { + String categoryCode = ""; + String categoryPid = ISysCategoryService.ROOT_PID_VALUE; + String parentCode = null; + if (oConvertUtils.isNotEmpty(sysCategory.getPid())) { + categoryPid = sysCategory.getPid(); + + //PID 不是根节点 说明需要设置父节点 hasChild 为1 + if (!ISysCategoryService.ROOT_PID_VALUE.equals(categoryPid)) { + SysCategory parent = baseMapper.selectById(categoryPid); + parentCode = parent.getCode(); + if (parent != null && !"1".equals(parent.getHasChild())) { + parent.setHasChild("1"); + baseMapper.updateById(parent); + } + } + } + //update-begin--Author:baihailong Date:20191209 for:分类字典编码规则生成器做成公用配置 + JSONObject formData = new JSONObject(); + formData.put("pid", categoryPid); + categoryCode = (String) FillRuleUtil.executeRule(FillRuleConstant.CATEGORY, formData); + //update-end--Author:baihailong Date:20191209 for:分类字典编码规则生成器做成公用配置 + sysCategory.setCode(categoryCode); + sysCategory.setPid(categoryPid); + baseMapper.insert(sysCategory); + } + + @Override + public void updateSysCategory(SysCategory sysCategory) { + if (oConvertUtils.isEmpty(sysCategory.getPid())) { + sysCategory.setPid(ISysCategoryService.ROOT_PID_VALUE); + } else { + //如果当前节点父ID不为空 则设置父节点的hasChild 为1 + SysCategory parent = baseMapper.selectById(sysCategory.getPid()); + if (parent != null && !"1".equals(parent.getHasChild())) { + parent.setHasChild("1"); + baseMapper.updateById(parent); + } + } + baseMapper.updateById(sysCategory); + } + + @Override + public List queryListByCode(String pcode) throws JeecgBootException { + String pid = ROOT_PID_VALUE; + if (oConvertUtils.isNotEmpty(pcode)) { + List list = baseMapper.selectList(new LambdaQueryWrapper().eq(SysCategory::getCode, pcode)); + if (list == null || list.size() == 0) { + throw new JeecgBootException("该编码【" + pcode + "】不存在,请核实!"); + } + if (list.size() > 1) { + throw new JeecgBootException("该编码【" + pcode + "】存在多个,请核实!"); + } + pid = list.get(0).getId(); + } + return baseMapper.queryListByPid(pid, null); + } + + @Override + public List queryListByPid(String pid) { + if (oConvertUtils.isEmpty(pid)) { + pid = ROOT_PID_VALUE; + } + return baseMapper.queryListByPid(pid, null); + } + + @Override + public List queryListByPid(String pid, Map condition) { + if (oConvertUtils.isEmpty(pid)) { + pid = ROOT_PID_VALUE; + } + return baseMapper.queryListByPid(pid, condition); + } + + @Override + public String queryIdByCode(String code) { + return baseMapper.queryIdByCode(code); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteSysCategory(String ids) { + String allIds = this.queryTreeChildIds(ids); + String pids = this.queryTreePids(ids); + //1.删除时将节点下所有子节点一并删除 + this.baseMapper.deleteBatchIds(Arrays.asList(allIds.split(","))); + //2.将父节点中已经没有下级的节点,修改为没有子节点 + if (oConvertUtils.isNotEmpty(pids)) { + LambdaUpdateWrapper updateWrapper = new UpdateWrapper() + .lambda() + .in(SysCategory::getId, Arrays.asList(pids.split(","))) + .set(SysCategory::getHasChild, "0"); + this.update(updateWrapper); + } + } + + /** + * 查询节点下所有子节点 + * + * @param ids + * @return + */ + private String queryTreeChildIds(String ids) { + //获取id数组 + String[] idArr = ids.split(","); + StringBuffer sb = new StringBuffer(); + for (String pidVal : idArr) { + if (pidVal != null) { + if (!sb.toString().contains(pidVal)) { + if (sb.toString().length() > 0) { + sb.append(","); + } + sb.append(pidVal); + this.getTreeChildIds(pidVal, sb); + } + } + } + return sb.toString(); + } + + /** + * 查询需修改标识的父节点ids + * + * @param ids + * @return + */ + private String queryTreePids(String ids) { + StringBuffer sb = new StringBuffer(); + //获取id数组 + String[] idArr = ids.split(","); + for (String id : idArr) { + if (id != null) { + SysCategory category = this.baseMapper.selectById(id); + //根据id查询pid值 + String metaPid = category.getPid(); + //查询此节点上一级是否还有其他子节点 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysCategory::getPid, metaPid); + queryWrapper.notIn(SysCategory::getId, Arrays.asList(idArr)); + List dataList = this.baseMapper.selectList(queryWrapper); + if ((dataList == null || dataList.size() == 0) && !Arrays.asList(idArr).contains(metaPid) + && !sb.toString().contains(metaPid)) { + //如果当前节点原本有子节点 现在木有了,更新状态 + sb.append(metaPid).append(","); + } + } + } + if (sb.toString().endsWith(",")) { + sb = sb.deleteCharAt(sb.length() - 1); + } + return sb.toString(); + } + + /** + * 递归 根据父id获取子节点id + * + * @param pidVal + * @param sb + * @return + */ + private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysCategory::getPid, pidVal); + List dataList = baseMapper.selectList(queryWrapper); + if (dataList != null && dataList.size() > 0) { + for (SysCategory category : dataList) { + if (!sb.toString().contains(category.getId())) { + sb.append(",").append(category.getId()); + } + this.getTreeChildIds(category.getId(), sb); + } + } + return sb; + } + + @Override + public List loadDictItem(String ids) { + return this.loadDictItem(ids, true); + } + + @Override + public List loadDictItem(String ids, boolean delNotExist) { + String[] idArray = ids.split(","); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.in(SysCategory::getId, Arrays.asList(idArray)); + // 查询数据 + List list = super.list(query); + // 取出name并返回 + List textList; + // update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ---- + if (delNotExist) { + textList = list.stream().map(SysCategory::getName).collect(Collectors.toList()); + } else { + textList = new ArrayList<>(); + for (String id : idArray) { + List res = list.stream().filter(i -> id.equals(i.getId())).collect(Collectors.toList()); + textList.add(res.size() > 0 ? res.get(0).getName() : id); + } + } + // update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ---- + return textList; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCheckRuleServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCheckRuleServiceImpl.java new file mode 100644 index 0000000..1bbec67 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysCheckRuleServiceImpl.java @@ -0,0 +1,98 @@ +package digital.system.jeecg.system.service.impl; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysCheckRule; +import digital.system.jeecg.system.mapper.SysCheckRuleMapper; +import digital.system.jeecg.system.service.ISysCheckRuleService; + +import java.util.regex.Pattern; + +/** + * @Description: 编码校验规则 + * @Author: zita + * @Date: 2020-02-04 + * @Version: V1.0 + */ +@Service +public class SysCheckRuleServiceImpl extends ServiceImpl implements ISysCheckRuleService { + + /** + * 位数特殊符号,用于检查整个值,而不是裁剪某一段 + */ + private final String CHECK_ALL_SYMBOL = "*"; + + @Override + public SysCheckRule getByCode(String ruleCode) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysCheckRule::getRuleCode, ruleCode); + return super.getOne(queryWrapper); + } + + /** + * 通过用户设定的自定义校验规则校验传入的值 + * + * @param checkRule + * @param value + * @return 返回 null代表通过校验,否则就是返回的错误提示文本 + */ + @Override + public JSONObject checkValue(SysCheckRule checkRule, String value) { + if (checkRule != null && StringUtils.isNotBlank(value)) { + String ruleJson = checkRule.getRuleJson(); + if (StringUtils.isNotBlank(ruleJson)) { + // 开始截取的下标,根据规则的顺序递增,但是 * 号不计入递增范围 + int beginIndex = 0; + JSONArray rules = JSON.parseArray(ruleJson); + for (int i = 0; i < rules.size(); i++) { + JSONObject result = new JSONObject(); + JSONObject rule = rules.getJSONObject(i); + // 位数 + String digits = rule.getString("digits"); + result.put("digits", digits); + // 验证规则 + String pattern = rule.getString("pattern"); + result.put("pattern", pattern); + // 未通过时的提示文本 + String message = rule.getString("message"); + result.put("message", message); + + // 根据用户设定的区间,截取字符串进行验证 + String checkValue; + // 是否检查整个值而不截取 + if (CHECK_ALL_SYMBOL.equals(digits)) { + checkValue = value; + } else { + int num = Integer.parseInt(digits); + int endIndex = beginIndex + num; + // 如果结束下标大于给定的值的长度,则取到最后一位 + endIndex = endIndex > value.length() ? value.length() : endIndex; + // 如果开始下标大于结束下标,则说明用户还尚未输入到该位置,直接赋空值 + if (beginIndex > endIndex) { + checkValue = ""; + } else { + checkValue = value.substring(beginIndex, endIndex); + } + result.put("beginIndex", beginIndex); + result.put("endIndex", endIndex); + beginIndex += num; + } + result.put("checkValue", checkValue); + boolean passed = Pattern.matches(pattern, checkValue); + result.put("passed", passed); + // 如果没有通过校验就返回错误信息 + if (!passed) { + return result; + } + } + } + } + return null; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataLogServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataLogServiceImpl.java new file mode 100644 index 0000000..20106f1 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataLogServiceImpl.java @@ -0,0 +1,37 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysDataLog; +import digital.system.jeecg.system.mapper.SysDataLogMapper; +import digital.system.jeecg.system.service.ISysDataLogService; + +/** + * @Description: 系统数据日志实现类 + * @author: smcp + */ +@Service +public class SysDataLogServiceImpl extends ServiceImpl implements ISysDataLogService { + @Autowired + private SysDataLogMapper logMapper; + + /** + * 添加数据日志 + */ + @Override + public void addDataLog(String tableName, String dataId, String dataContent) { + String versionNumber = "0"; + String dataVersion = logMapper.queryMaxDataVer(tableName, dataId); + if (dataVersion != null) { + versionNumber = String.valueOf(Integer.parseInt(dataVersion) + 1); + } + SysDataLog log = new SysDataLog(); + log.setDataTable(tableName); + log.setDataId(dataId); + log.setDataContent(dataContent); + log.setDataVersion(versionNumber); + this.save(log); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataSourceServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataSourceServiceImpl.java new file mode 100644 index 0000000..658b920 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDataSourceServiceImpl.java @@ -0,0 +1,18 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysDataSource; +import digital.system.jeecg.system.mapper.SysDataSourceMapper; +import digital.system.jeecg.system.service.ISysDataSourceService; + +/** + * @Description: 多数据源管理 + * @Author: zita + * @Date: 2019-12-25 + * @Version: V1.0 + */ +@Service +public class SysDataSourceServiceImpl extends ServiceImpl implements ISysDataSourceService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartPermissionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartPermissionServiceImpl.java new file mode 100644 index 0000000..e4ce0e9 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartPermissionServiceImpl.java @@ -0,0 +1,111 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.system.jeecg.system.entity.SysDepartPermission; +import digital.system.jeecg.system.entity.SysDepartRole; +import digital.system.jeecg.system.entity.SysDepartRolePermission; +import digital.system.jeecg.system.entity.SysPermissionDataRule; +import digital.system.jeecg.system.mapper.SysDepartPermissionMapper; +import digital.system.jeecg.system.mapper.SysDepartRoleMapper; +import digital.system.jeecg.system.mapper.SysDepartRolePermissionMapper; +import digital.system.jeecg.system.mapper.SysPermissionDataRuleMapper; +import digital.system.jeecg.system.service.ISysDepartPermissionService; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description: 部门权限表 + * @Author: zita + * @Date: 2020-02-11 + * @Version: V1.0 + */ +@Service +public class SysDepartPermissionServiceImpl extends ServiceImpl implements ISysDepartPermissionService { + @Resource + private SysPermissionDataRuleMapper ruleMapper; + + @Resource + private SysDepartRoleMapper sysDepartRoleMapper; + + @Resource + private SysDepartRolePermissionMapper departRolePermissionMapper; + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveDepartPermission(String departId, String permissionIds, String lastPermissionIds) { + List add = getDiff(lastPermissionIds, permissionIds); + if (add != null && add.size() > 0) { + List list = new ArrayList(); + for (String p : add) { + if (oConvertUtils.isNotEmpty(p)) { + SysDepartPermission rolepms = new SysDepartPermission(departId, p); + list.add(rolepms); + } + } + this.saveBatch(list); + } + List delete = getDiff(permissionIds, lastPermissionIds); + if (delete != null && delete.size() > 0) { + for (String permissionId : delete) { + this.remove(new QueryWrapper().lambda().eq(SysDepartPermission::getDepartId, departId).eq(SysDepartPermission::getPermissionId, permissionId)); + //删除部门权限时,删除部门角色中已授权的权限 + List sysDepartRoleList = sysDepartRoleMapper.selectList(new LambdaQueryWrapper().eq(SysDepartRole::getDepartId, departId)); + List roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList()); + if (roleIds != null && roleIds.size() > 0) { + departRolePermissionMapper.delete(new LambdaQueryWrapper().eq(SysDepartRolePermission::getPermissionId, permissionId)); + } + } + } + } + + @Override + public List getPermRuleListByDeptIdAndPermId(String departId, String permissionId) { + SysDepartPermission departPermission = this.getOne(new QueryWrapper().lambda().eq(SysDepartPermission::getDepartId, departId).eq(SysDepartPermission::getPermissionId, permissionId)); + if (departPermission != null && oConvertUtils.isNotEmpty(departPermission.getDataRuleIds())) { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.in(SysPermissionDataRule::getId, Arrays.asList(departPermission.getDataRuleIds().split(","))); + query.orderByDesc(SysPermissionDataRule::getCreateTime); + List permRuleList = this.ruleMapper.selectList(query); + return permRuleList; + } else { + return null; + } + } + + /** + * 从diff中找出main中没有的元素 + * + * @param main + * @param diff + * @return + */ + private List getDiff(String main, String diff) { + if (oConvertUtils.isEmpty(diff)) { + return null; + } + if (oConvertUtils.isEmpty(main)) { + return Arrays.asList(diff.split(",")); + } + + String[] mainArr = main.split(","); + String[] diffArr = diff.split(","); + Map map = new HashMap(5); + for (String string : mainArr) { + map.put(string, 1); + } + List res = new ArrayList(); + for (String key : diffArr) { + if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) { + res.add(key); + } + } + return res; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRolePermissionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRolePermissionServiceImpl.java new file mode 100644 index 0000000..a25402d --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRolePermissionServiceImpl.java @@ -0,0 +1,87 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysDepartRolePermission; +import digital.system.jeecg.system.mapper.SysDepartRolePermissionMapper; +import digital.system.jeecg.system.service.ISysDepartRolePermissionService; +import digital.util.util.IpUtils; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + * @Description: 部门角色权限 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +@Service +public class SysDepartRolePermissionServiceImpl extends ServiceImpl implements ISysDepartRolePermissionService { + + @Override + public void saveDeptRolePermission(String roleId, String permissionIds, String lastPermissionIds) { + String ip = ""; + try { + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //获取IP地址 + ip = IpUtils.getIpAddr(request); + } catch (Exception e) { + ip = "127.0.0.1"; + } + List add = getDiff(lastPermissionIds, permissionIds); + if (add != null && add.size() > 0) { + List list = new ArrayList(); + for (String p : add) { + if (oConvertUtils.isNotEmpty(p)) { + SysDepartRolePermission rolepms = new SysDepartRolePermission(roleId, p); + rolepms.setOperateDate(new Date()); + rolepms.setOperateIp(ip); + list.add(rolepms); + } + } + this.saveBatch(list); + } + + List delete = getDiff(permissionIds, lastPermissionIds); + if (delete != null && delete.size() > 0) { + for (String permissionId : delete) { + this.remove(new QueryWrapper().lambda().eq(SysDepartRolePermission::getRoleId, roleId).eq(SysDepartRolePermission::getPermissionId, permissionId)); + } + } + } + + /** + * 从diff中找出main中没有的元素 + * + * @param main + * @param diff + * @return + */ + private List getDiff(String main, String diff) { + if (oConvertUtils.isEmpty(diff)) { + return null; + } + if (oConvertUtils.isEmpty(main)) { + return Arrays.asList(diff.split(",")); + } + + String[] mainArr = main.split(","); + String[] diffArr = diff.split(","); + Map map = new HashMap(5); + for (String string : mainArr) { + map.put(string, 1); + } + List res = new ArrayList(); + for (String key : diffArr) { + if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) { + res.add(key); + } + } + return res; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleServiceImpl.java new file mode 100644 index 0000000..a36521a --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleServiceImpl.java @@ -0,0 +1,24 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysDepartRole; +import digital.system.jeecg.system.mapper.SysDepartRoleMapper; +import digital.system.jeecg.system.service.ISysDepartRoleService; + +import java.util.List; + +/** + * @Description: 部门角色 + * @Author: zita + * @Date: 2020-02-12 + * @Version: V1.0 + */ +@Service +public class SysDepartRoleServiceImpl extends ServiceImpl implements ISysDepartRoleService { + + @Override + public List queryDeptRoleByDeptAndUser(String orgCode, String userId) { + return this.baseMapper.queryDeptRoleByDeptAndUser(orgCode, userId); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleUserServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleUserServiceImpl.java new file mode 100644 index 0000000..a0d8f3c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartRoleUserServiceImpl.java @@ -0,0 +1,93 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.system.jeecg.system.entity.SysDepartRole; +import digital.system.jeecg.system.entity.SysDepartRoleUser; +import digital.system.jeecg.system.mapper.SysDepartRoleMapper; +import digital.system.jeecg.system.mapper.SysDepartRoleUserMapper; +import digital.system.jeecg.system.service.ISysDepartRoleUserService; +import digital.util.util.oConvertUtils; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * @Description: 部门角色人员信息 + * @Author: zita + * @Date: 2020-02-13 + * @Version: V1.0 + */ +@Service +public class SysDepartRoleUserServiceImpl extends ServiceImpl implements ISysDepartRoleUserService { + @Autowired + private SysDepartRoleMapper sysDepartRoleMapper; + + @Override + public void deptRoleUserAdd(String userId, String newRoleId, String oldRoleId) { + List add = getDiff(oldRoleId, newRoleId); + if (add != null && add.size() > 0) { + List list = new ArrayList<>(); + for (String roleId : add) { + if (oConvertUtils.isNotEmpty(roleId)) { + SysDepartRoleUser rolepms = new SysDepartRoleUser(userId, roleId); + list.add(rolepms); + } + } + this.saveBatch(list); + } + List remove = getDiff(newRoleId, oldRoleId); + if (remove != null && remove.size() > 0) { + for (String roleId : remove) { + this.remove(new QueryWrapper().lambda().eq(SysDepartRoleUser::getUserId, userId).eq(SysDepartRoleUser::getDroleId, roleId)); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void removeDeptRoleUser(List userIds, String depId) { + for (String userId : userIds) { + List sysDepartRoleList = sysDepartRoleMapper.selectList(new QueryWrapper().eq("depart_id", depId)); + List roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList()); + if (roleIds != null && roleIds.size() > 0) { + QueryWrapper query = new QueryWrapper<>(); + query.eq("user_id", userId).in("drole_id", roleIds); + this.remove(query); + } + } + } + + /** + * 从diff中找出main中没有的元素 + * + * @param main + * @param diff + * @return + */ + private List getDiff(String main, String diff) { + if (oConvertUtils.isEmpty(diff)) { + return null; + } + if (oConvertUtils.isEmpty(main)) { + return Arrays.asList(diff.split(",")); + } + + String[] mainArr = main.split(","); + String[] diffArr = diff.split(","); + Map map = new HashMap(5); + for (String string : mainArr) { + map.put(string, 1); + } + List res = new ArrayList(); + for (String key : diffArr) { + if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) { + res.add(key); + } + } + return res; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartServiceImpl.java new file mode 100644 index 0000000..45f04ff --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDepartServiceImpl.java @@ -0,0 +1,682 @@ +package digital.system.jeecg.system.service.impl; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.base.constant.CacheConstant; +import digital.base.constant.CommonConstant; +import digital.base.constant.FillRuleConstant; +import digital.system.jeecg.system.entity.*; +import digital.system.jeecg.system.mapper.*; +import digital.system.jeecg.system.model.DepartIdModel; +import digital.system.jeecg.system.model.SysDepartTreeModel; +import digital.system.jeecg.system.service.ISysDepartService; +import digital.system.jeecg.system.util.FindsDepartsChildrenUtil; +import digital.util.util.FillRuleUtil; +import digital.util.util.YouBianCodeUtil; +import digital.util.util.oConvertUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.function.Consumer; + +/** + *

+ * 部门表 服务实现类 + *

+ * + * @Author Steve + * @Since 2019-01-22 + */ +@Service +public class SysDepartServiceImpl extends ServiceImpl implements ISysDepartService { + + @Autowired + private SysUserDepartMapper userDepartMapper; + @Autowired + private SysDepartRoleMapper sysDepartRoleMapper; + @Autowired + private SysDepartPermissionMapper departPermissionMapper; + @Autowired + private SysDepartRolePermissionMapper departRolePermissionMapper; + @Autowired + private SysDepartRoleUserMapper departRoleUserMapper; + @Autowired + private SysUserMapper sysUserMapper; + + @Override + public List queryMyDeptTreeList(String departIds) { + //根据部门id获取所负责部门 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + String[] codeArr = this.getMyDeptParentOrgCode(departIds); + for (int i = 0; i < codeArr.length; i++) { + query.or().likeRight(SysDepart::getOrgCode, codeArr[i]); + } + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + query.orderByAsc(SysDepart::getDepartOrder); + //将父节点ParentId设为null + List listDepts = this.list(query); + for (int i = 0; i < codeArr.length; i++) { + for (SysDepart dept : listDepts) { + if (dept.getOrgCode().equals(codeArr[i])) { + dept.setParentId(null); + } + } + } + // 调用wrapTreeDataToTreeList方法生成树状数据 + List listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(listDepts); + return listResult; + } + + /** + * queryTreeList 对应 queryTreeList 查询所有的部门数据,以树结构形式响应给前端 + */ + @Override + @Cacheable(value = CacheConstant.SYS_DEPARTS_CACHE) + public List queryTreeList() { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + query.orderByAsc(SysDepart::getDepartOrder); + List list = this.list(query); + //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + //设置用户id,让前台显示 +// this.setUserIdsByDepList(list); + //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + // 调用wrapTreeDataToTreeList方法生成树状数据 + List listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list); + return listResult; + } + + /** + * queryTreeList 根据部门id查询,前端回显调用 + */ + @Override + public List queryTreeList(String ids) { + List listResult = new ArrayList<>(); + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + if (oConvertUtils.isNotEmpty(ids)) { + query.in(true, SysDepart::getId, ids.split(",")); + } + query.orderByAsc(SysDepart::getDepartOrder); + List list = this.list(query); + for (SysDepart depart : list) { + listResult.add(new SysDepartTreeModel(depart)); + } + return listResult; + + } + + @Cacheable(value = CacheConstant.SYS_DEPART_IDS_CACHE) + @Override + public List queryDepartIdTreeList() { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + query.orderByAsc(SysDepart::getDepartOrder); + List list = this.list(query); + // 调用wrapTreeDataToTreeList方法生成树状数据 + List listResult = FindsDepartsChildrenUtil.wrapTreeDataToDepartIdTreeList(list); + return listResult; + } + + /** + * saveDepartData 对应 add 保存用户在页面添加的新的部门对象数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void saveDepartData(SysDepart sysDepart, String username) { + if (sysDepart != null && username != null) { + if (sysDepart.getParentId() == null) { + sysDepart.setParentId(""); + } + String s = UUID.randomUUID().toString().replace("-", ""); + sysDepart.setId(s); + // 先判断该对象有无父级ID,有则意味着不是最高级,否则意味着是最高级 + // 获取父级ID + String parentId = sysDepart.getParentId(); + //update-begin--Author:baihailong Date:20191209 for:部门编码规则生成器做成公用配置 + JSONObject formData = new JSONObject(); + formData.put("parentId", parentId); + String[] codeArray = (String[]) FillRuleUtil.executeRule(FillRuleConstant.DEPART, formData); + //update-end--Author:baihailong Date:20191209 for:部门编码规则生成器做成公用配置 + sysDepart.setOrgCode(codeArray[0]); + String orgType = codeArray[1]; + sysDepart.setOrgType(String.valueOf(orgType)); + sysDepart.setCreateTime(new Date()); + sysDepart.setDelFlag(CommonConstant.DEL_FLAG_0.toString()); + this.save(sysDepart); + //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + //新增部门的时候新增负责部门 + if (oConvertUtils.isNotEmpty(sysDepart.getDirectorUserIds())) { + this.addDepartByUserIds(sysDepart, sysDepart.getDirectorUserIds()); + } + //update-end---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + } + + } + + /** + * saveDepartData 的调用方法,生成部门编码和部门类型(作废逻辑) + * + * @param parentId + * @return + * @deprecated + */ + private String[] generateOrgCode(String parentId) { + //update-begin--Author:Steve Date:20190201 for:组织机构添加数据代码调整 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + LambdaQueryWrapper query1 = new LambdaQueryWrapper(); + String[] strArray = new String[2]; + // 创建一个List集合,存储查询返回的所有SysDepart对象 + List departList = new ArrayList<>(); + // 定义新编码字符串 + String newOrgCode = ""; + // 定义旧编码字符串 + String oldOrgCode = ""; + // 定义部门类型 + String orgType = ""; + // 如果是最高级,则查询出同级的org_code, 调用工具类生成编码并返回 + if (oConvertUtils.isEmpty(parentId)) { + // 线判断数据库中的表是否为空,空则直接返回初始编码 + query1.eq(SysDepart::getParentId, "").or().isNull(SysDepart::getParentId); + query1.orderByDesc(SysDepart::getOrgCode); + departList = this.list(query1); + if (departList == null || departList.size() == 0) { + strArray[0] = YouBianCodeUtil.getNextYouBianCode(null); + strArray[1] = "1"; + return strArray; + } else { + SysDepart depart = departList.get(0); + oldOrgCode = depart.getOrgCode(); + orgType = depart.getOrgType(); + newOrgCode = YouBianCodeUtil.getNextYouBianCode(oldOrgCode); + } + } else + + { // 反之则查询出所有同级的部门,获取结果后有两种情况,有同级和没有同级 + // 封装查询同级的条件 + query.eq(SysDepart::getParentId, parentId); + // 降序排序 + query.orderByDesc(SysDepart::getOrgCode); + // 查询出同级部门的集合 + List parentList = this.list(query); + // 查询出父级部门 + SysDepart depart = this.getById(parentId); + // 获取父级部门的Code + String parentCode = depart.getOrgCode(); + // 根据父级部门类型算出当前部门的类型 + orgType = String.valueOf(Integer.valueOf(depart.getOrgType()) + 1); + // 处理同级部门为null的情况 + if (parentList == null || parentList.size() == 0) { + // 直接生成当前的部门编码并返回 + newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, null); + } else { //处理有同级部门的情况 + // 获取同级部门的编码,利用工具类 + String subCode = parentList.get(0).getOrgCode(); + // 返回生成的当前部门编码 + newOrgCode = YouBianCodeUtil.getSubYouBianCode(parentCode, subCode); + } + } + // 返回最终封装了部门编码和部门类型的数组 + strArray[0] = newOrgCode; + strArray[1] = orgType; + return strArray; + //update-end--Author:Steve Date:20190201 for:组织机构添加数据代码调整 + } + + + /** + * removeDepartDataById 对应 delete方法 根据ID删除相关部门数据 + * + */ + /* + * @Override + * + * @Transactional public boolean removeDepartDataById(String id) { + * System.out.println("要删除的ID 为=============================>>>>>"+id); boolean + * flag = this.removeById(id); return flag; } + */ + + /** + * updateDepartDataById 对应 edit 根据部门主键来更新对应的部门数据 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean updateDepartDataById(SysDepart sysDepart, String username) { + if (sysDepart != null && username != null) { + sysDepart.setUpdateTime(new Date()); + sysDepart.setUpdateBy(username); + this.updateById(sysDepart); + //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + //修改部门管理的时候,修改负责部门 +// this.updateChargeDepart(sysDepart); + //update-begin---author:wangshuai ---date:20220307 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + return true; + } else { + return false; + } + + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteBatchWithChildren(List ids) { + List idList = new ArrayList(); + for (String id : ids) { + idList.add(id); + this.checkChildrenExists(id, idList); + } + this.removeByIds(idList); + //根据部门id获取部门角色id + List roleIdList = new ArrayList<>(); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDepartRole::getId).in(SysDepartRole::getDepartId, idList); + List depRoleList = sysDepartRoleMapper.selectList(query); + for (SysDepartRole deptRole : depRoleList) { + roleIdList.add(deptRole.getId()); + } + //根据部门id删除用户与部门关系 + userDepartMapper.delete(new LambdaQueryWrapper().in(SysUserDepart::getDepId, idList)); + //根据部门id删除部门授权 + departPermissionMapper.delete(new LambdaQueryWrapper().in(SysDepartPermission::getDepartId, idList)); + //根据部门id删除部门角色 + sysDepartRoleMapper.delete(new LambdaQueryWrapper().in(SysDepartRole::getDepartId, idList)); + if (roleIdList != null && roleIdList.size() > 0) { + //根据角色id删除部门角色授权 + departRolePermissionMapper.delete(new LambdaQueryWrapper().in(SysDepartRolePermission::getRoleId, roleIdList)); + //根据角色id删除部门角色用户信息 + departRoleUserMapper.delete(new LambdaQueryWrapper().in(SysDepartRoleUser::getDroleId, roleIdList)); + } + } + + @Override + public List getSubDepIdsByDepId(String departId) { + return this.baseMapper.getSubDepIdsByDepId(departId); + } + + @Override + public List getMySubDepIdsByDepId(String departIds) { + //根据部门id获取所负责部门 + String[] codeArr = this.getMyDeptParentOrgCode(departIds); + if (codeArr == null || codeArr.length == 0) { + return null; + } + return this.baseMapper.getSubDepIdsByOrgCodes(codeArr); + } + + /** + *

+ * 根据关键字搜索相关的部门数据 + *

+ */ + @Override + public List searchByKeyWord(String keyWord, String myDeptSearch, String departIds) { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + List newList = new ArrayList<>(); + //myDeptSearch不为空时为我的部门搜索,只搜索所负责部门 +// if (!StringUtil.isNullOrEmpty(myDeptSearch)) { +// //departIds 为空普通用户或没有管理部门 +//// if (StringUtil.isNullOrEmpty(departIds)) { +//// return newList; +//// } +// //根据部门id获取所负责部门 +// String[] codeArr = this.getMyDeptParentOrgCode(departIds); +// //update-begin-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效! +// if (codeArr != null && codeArr.length > 0) { +// query.nested(i -> { +// for (String s : codeArr) { +// i.or().likeRight(SysDepart::getOrgCode, s); +// } +// }); +// } +// //update-end-author:taoyan date:20220104 for:/issues/3311 当用户属于两个部门的时候,且这两个部门没有上下级关系,我的部门-部门名称查询条件模糊搜索失效! +// query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); +// } + query.like(SysDepart::getDepartName, keyWord); + //update-begin--Author:huangzhilin Date:20140417 for:[bugfree号]组织机构搜索回显优化-------------------- + SysDepartTreeModel model = new SysDepartTreeModel(); + List departList = this.list(query); + if (departList.size() > 0) { + for (SysDepart depart : departList) { + model = new SysDepartTreeModel(depart); + model.setChildren(null); + //update-end--Author:huangzhilin Date:20140417 for:[bugfree号]组织机构搜索功回显优化---------------------- + newList.add(model); + } + return newList; + } + return null; + } + + /** + * 根据部门id删除并且删除其可能存在的子级任何部门 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public boolean delete(String id) { + List idList = new ArrayList<>(); + idList.add(id); + this.checkChildrenExists(id, idList); + //清空部门树内存 + //FindsDepartsChildrenUtil.clearDepartIdModel(); + boolean ok = this.removeByIds(idList); + //根据部门id获取部门角色id + List roleIdList = new ArrayList<>(); + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.select(SysDepartRole::getId).in(SysDepartRole::getDepartId, idList); + List depRoleList = sysDepartRoleMapper.selectList(query); + for (SysDepartRole deptRole : depRoleList) { + roleIdList.add(deptRole.getId()); + } + //根据部门id删除用户与部门关系 + userDepartMapper.delete(new LambdaQueryWrapper().in(SysUserDepart::getDepId, idList)); + //根据部门id删除部门授权 + departPermissionMapper.delete(new LambdaQueryWrapper().in(SysDepartPermission::getDepartId, idList)); + //根据部门id删除部门角色 + sysDepartRoleMapper.delete(new LambdaQueryWrapper().in(SysDepartRole::getDepartId, idList)); + if (roleIdList != null && roleIdList.size() > 0) { + //根据角色id删除部门角色授权 + departRolePermissionMapper.delete(new LambdaQueryWrapper().in(SysDepartRolePermission::getRoleId, roleIdList)); + //根据角色id删除部门角色用户信息 + departRoleUserMapper.delete(new LambdaQueryWrapper().in(SysDepartRoleUser::getDroleId, roleIdList)); + } + return ok; + } + + /** + * delete 方法调用 + * + * @param id + * @param idList + */ + private void checkChildrenExists(String id, List idList) { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getParentId, id); + List departList = this.list(query); + if (departList != null && departList.size() > 0) { + for (SysDepart depart : departList) { + idList.add(depart.getId()); + this.checkChildrenExists(depart.getId(), idList); + } + } + } + + @Override + public List queryUserDeparts(String userId) { + return baseMapper.queryUserDeparts(userId); + } + + @Override + public List queryDepartsByUsername(String username) { + return baseMapper.queryDepartsByUsername(username); + } + + /** + * 根据用户所负责部门ids获取父级部门编码 + * + * @param departIds + * @return + */ + private String[] getMyDeptParentOrgCode(String departIds) { + //根据部门id查询所负责部门 + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + query.in(SysDepart::getId, Arrays.asList(departIds.split(","))); + query.orderByAsc(SysDepart::getOrgCode); + List list = this.list(query); + //查找根部门 + if (list == null || list.size() == 0) { + return null; + } + String orgCode = this.getMyDeptParentNode(list); + String[] codeArr = orgCode.split(","); + return codeArr; + } + + /** + * 获取负责部门父节点 + * + * @param list + * @return + */ + private String getMyDeptParentNode(List list) { + Map map = new HashMap(5); + //1.先将同一公司归类 + for (SysDepart dept : list) { + String code = dept.getOrgCode().substring(0, 3); + if (map.containsKey(code)) { + String mapCode = map.get(code) + "," + dept.getOrgCode(); + map.put(code, mapCode); + } else { + map.put(code, dept.getOrgCode()); + } + } + StringBuffer parentOrgCode = new StringBuffer(); + //2.获取同一公司的根节点 + for (String str : map.values()) { + String[] arrStr = str.split(","); + parentOrgCode.append(",").append(this.getMinLengthNode(arrStr)); + } + return parentOrgCode.substring(1); + } + + /** + * 获取同一公司中部门编码长度最小的部门 + * + * @param str + * @return + */ + private String getMinLengthNode(String[] str) { + int min = str[0].length(); + String orgCode = str[0]; + for (int i = 1; i < str.length; i++) { + if (str[i].length() <= min) { + min = str[i].length(); + orgCode = orgCode + "," + str[i]; + } + } + return orgCode; + } + + /** + * 获取部门树信息根据关键字 + * + * @param keyWord + * @return + */ + @Override + public List queryTreeByKeyWord(String keyWord) { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + query.orderByAsc(SysDepart::getDepartOrder); + List list = this.list(query); + // 调用wrapTreeDataToTreeList方法生成树状数据 + List listResult = FindsDepartsChildrenUtil.wrapTreeDataToTreeList(list); + List treelist = new ArrayList<>(); + if (StringUtils.isNotBlank(keyWord)) { + this.getTreeByKeyWord(keyWord, listResult, treelist); + } else { + return listResult; + } + return treelist; + } + + /** + * 根据parentId查询部门树 + * + * @param parentId + * @param ids 前端回显传递 + * @return + */ + @Override + public List queryTreeListByPid(String parentId, String ids) { + Consumer> square = i -> { + if (oConvertUtils.isNotEmpty(ids)) { + i.in(SysDepart::getId, ids.split(",")); + } else { + if (oConvertUtils.isEmpty(parentId)) { + i.and(q -> q.isNull(true, SysDepart::getParentId).or().eq(true, SysDepart::getParentId, "")); + } else { + i.eq(true, SysDepart::getParentId, parentId); + } + } + }; + LambdaQueryWrapper lqw = new LambdaQueryWrapper(); + lqw.eq(true, SysDepart::getDelFlag, CommonConstant.DEL_FLAG_0.toString()); + lqw.func(square); + lqw.orderByDesc(SysDepart::getDepartOrder); + List list = list(lqw); + //update-begin---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + //设置用户id,让前台显示 +// this.setUserIdsByDepList(list); + //update-end---author:wangshuai ---date:20220316 for:[JTC-119]在部门管理菜单下设置部门负责人 创建用户的时候不需要处理 + List records = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + SysDepart depart = list.get(i); + SysDepartTreeModel treeModel = new SysDepartTreeModel(depart); + //TODO 异步树加载key拼接__+时间戳,以便于每次展开节点会刷新数据 + //treeModel.setKey(treeModel.getKey()+"__"+System.currentTimeMillis()); + treeModel.setKey(treeModel.getKey()); + Integer count = this.baseMapper.queryCountByPid(depart.getId()); + if (count > 0) { + treeModel.setIsLeaf(false); + } else { + treeModel.setIsLeaf(true); + } + records.add(treeModel); + } + return records; + } + + @Override + public JSONObject queryAllParentIdByDepartId(String departId) { + JSONObject result = new JSONObject(); + for (String id : departId.split(",")) { + JSONObject all = this.queryAllParentId("id", id); + result.put(id, all); + } + return result; + } + + @Override + public JSONObject queryAllParentIdByOrgCode(String orgCode) { + JSONObject result = new JSONObject(); + for (String code : orgCode.split(",")) { + JSONObject all = this.queryAllParentId("org_code", code); + result.put(code, all); + } + return result; + } + + /** + * 查询某个部门的所有父ID信息 + * + * @param fieldName 字段名 + * @param value 值 + */ + private JSONObject queryAllParentId(String fieldName, String value) { + JSONObject data = new JSONObject(); + // 父ID集合,有序 + data.put("parentIds", new JSONArray()); + // 父ID的部门数据,key是id,value是数据 + data.put("parentMap", new JSONObject()); + this.queryAllParentIdRecursion(fieldName, value, data); + return data; + } + + /** + * 递归调用查询父部门接口 + */ + private void queryAllParentIdRecursion(String fieldName, String value, JSONObject data) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(fieldName, value); + SysDepart depart = super.getOne(queryWrapper); + if (depart != null) { + data.getJSONArray("parentIds").add(0, depart.getId()); + data.getJSONObject("parentMap").put(depart.getId(), depart); + if (oConvertUtils.isNotEmpty(depart.getParentId())) { + this.queryAllParentIdRecursion("id", depart.getParentId(), data); + } + } + } + + @Override + public SysDepart queryCompByOrgCode(String orgCode) { + int length = YouBianCodeUtil.ZHANWEI_LENGTH; + String compyOrgCode = orgCode.substring(0, length); + return this.baseMapper.queryCompByOrgCode(compyOrgCode); + } + + /** + * 根据id查询下级部门 + * + * @param pid + * @return + */ + @Override + public List queryDeptByPid(String pid) { + return this.baseMapper.queryDeptByPid(pid); + } + + /** + * 根据关键字筛选部门信息 + * + * @param keyWord + * @return + */ + public void getTreeByKeyWord(String keyWord, List allResult, List newResult) { + for (SysDepartTreeModel model : allResult) { + if (model.getDepartName().contains(keyWord)) { + newResult.add(model); + continue; + } else if (model.getChildren() != null) { + getTreeByKeyWord(keyWord, model.getChildren(), newResult); + } + } + } + + //update-begin---author:wangshuai ---date:20200308 for:[JTC-119]在部门管理菜单下设置部门负责人,新增方法添加部门负责人、删除负责部门负责人、查询部门对应的负责人 + + /** + * 通过用户id设置负责部门 + * + * @param sysDepart SysDepart部门对象 + * @param userIds 多个负责用户id + */ + public void addDepartByUserIds(SysDepart sysDepart, String userIds) { + //获取部门id,保存到用户 + String departId = sysDepart.getId(); + //循环用户id + String[] userIdArray = userIds.split(","); + for (String userId : userIdArray) { + //查询用户表增加负责部门 + SysUser sysUser = sysUserMapper.selectById(userId); + //如果部门id不为空,那么就需要拼接 +// if (oConvertUtils.isNotEmpty(sysUser.getDepartIds())) { +// if (!sysUser.getDepartIds().contains(departId)) { +// sysUser.setDepartIds(sysUser.getDepartIds() + "," + departId); +// } +// } else { +// sysUser.setDepartIds(departId); +// } + //设置身份为上级 +// sysUser.setUserIdentity(CommonConstant.USER_IDENTITY_2); + //跟新用户表 + sysUserMapper.updateById(sysUser); + //判断当前用户是否包含所属部门 + List userDepartList = userDepartMapper.getUserDepartByUid(userId); + boolean isExistDepId = userDepartList.stream().anyMatch(item -> departId.equals(item.getDepId())); + //如果不存在需要设置所属部门 + if (!isExistDepId) { + userDepartMapper.insert(new SysUserDepart(userId, departId)); + } + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictItemServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictItemServiceImpl.java new file mode 100644 index 0000000..dd16c1e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictItemServiceImpl.java @@ -0,0 +1,30 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysDictItem; +import digital.system.jeecg.system.mapper.SysDictItemMapper; +import digital.system.jeecg.system.service.ISysDictItemService; + +import java.util.List; + +/** + *

+ * 服务实现类 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Service +public class SysDictItemServiceImpl extends ServiceImpl implements ISysDictItemService { + + @Autowired + private SysDictItemMapper sysDictItemMapper; + + @Override + public List selectItemsByMainId(String mainId) { + return sysDictItemMapper.selectItemsByMainId(mainId); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictServiceImpl.java new file mode 100644 index 0000000..5bb754b --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysDictServiceImpl.java @@ -0,0 +1,449 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.apache.shiro.SecurityUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.base.constant.CacheConstant; +import digital.base.constant.CommonConstant; +import digital.base.constant.DictConstants; +import digital.base.vo.LoginUser; +import digital.bean.jeecg.vo.DictModel; +import digital.bean.jeecg.vo.DictModelMany; +import digital.bean.jeecg.vo.DictQuery; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysDict; +import digital.system.jeecg.system.entity.SysDictItem; +import digital.system.jeecg.system.mapper.SysDictItemMapper; +import digital.system.jeecg.system.mapper.SysDictMapper; +import digital.system.jeecg.system.model.TreeSelectModel; +import digital.system.jeecg.system.service.ISysDictService; +import digital.util.util.SqlInjectionUtil; +import digital.util.util.oConvertUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + *

+ * 字典表 服务实现类 + *

+ * + * @Author zhangweijian + * @since 2018-12-28 + */ +@Service +@Slf4j +public class SysDictServiceImpl extends ServiceImpl implements ISysDictService { + + @Autowired + private SysDictMapper sysDictMapper; + @Autowired + private SysDictItemMapper sysDictItemMapper; + + /** + * 通过查询指定code 获取字典 + * + * @param code + * @return + */ + @Override + @Cacheable(value = CacheConstant.SYS_DICT_CACHE, key = "#code", unless = "#result == null ") + public List queryDictItemsByCode(String code) { + log.debug("无缓存dictCache的时候调用这里!"); + return sysDictMapper.queryDictItemsByCode(code); + } + + @Override + @Cacheable(value = CacheConstant.SYS_ENABLE_DICT_CACHE, key = "#code", unless = "#result == null ") + public List queryEnableDictItemsByCode(String code) { + log.debug("无缓存dictCache的时候调用这里!"); + return sysDictMapper.queryEnableDictItemsByCode(code); + } + + @Override + public Map> queryDictItemsByCodeList(List dictCodeList) { + List list = sysDictMapper.queryDictItemsByCodeList(dictCodeList); + Map> dictMap = new HashMap(5); + for (DictModelMany dict : list) { + List dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>()); + dict.setDictCode(null); + dictItemList.add(new DictModel(dict.getValue(), dict.getText())); + } + return dictMap; + } + + @Override + public Map> queryAllDictItems() { + Map> res = new HashMap(5); + List ls = sysDictMapper.selectList(null); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper(); + queryWrapper.eq(SysDictItem::getStatus, 1); + queryWrapper.orderByAsc(SysDictItem::getSortOrder); + List sysDictItemList = sysDictItemMapper.selectList(queryWrapper); + + for (SysDict d : ls) { + List dictModelList = sysDictItemList.stream().filter(s -> d.getId().equals(s.getDictId())).map(item -> { + DictModel dictModel = new DictModel(); + dictModel.setText(item.getItemText()); + dictModel.setValue(item.getItemValue()); + return dictModel; + }).collect(Collectors.toList()); + res.put(d.getDictCode(), dictModelList); + } + log.debug("-------登录加载系统字典-----" + res.toString()); + return res; + } + + /** + * 通过查询指定code 获取字典值text + * + * @param code + * @param key + * @return + */ + + @Override + @Cacheable(value = CacheConstant.SYS_DICT_CACHE, key = "#code+':'+#key", unless = "#result == null ") + public String queryDictTextByKey(String code, String key) { + log.debug("无缓存dictText的时候调用这里!"); + return sysDictMapper.queryDictTextByKey(code, key); + } + + @Override + public Map> queryManyDictByKeys(List dictCodeList, List keys) { + List list = sysDictMapper.queryManyDictByKeys(dictCodeList, keys); + Map> dictMap = new HashMap(5); + for (DictModelMany dict : list) { + List dictItemList = dictMap.computeIfAbsent(dict.getDictCode(), i -> new ArrayList<>()); + dictItemList.add(new DictModel(dict.getValue(), dict.getText())); + } + return dictMap; + } + + /** + * 通过查询指定table的 text code 获取字典 + * dictTableCache采用redis缓存有效期10分钟 + * + * @param table + * @param text + * @param code + * @return + */ + @Override + //@Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE) + public List queryTableDictItemsByCode(String table, String text, String code) { + //权限过滤,只能查询账号下对应的数据 + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + log.debug("无缓存dictTableList的时候调用这里!"); + return sysDictMapper.queryTableDictItemsByCode(table, text, code); + } + + @Override + public List queryTableDictItemsByCodeAndFilter(String table, String text, String code, String filterSql) { + log.debug("无缓存dictTableList的时候调用这里!"); + return sysDictMapper.queryTableDictItemsByCodeAndFilter(table, text, code, filterSql); + } + + /** + * 通过查询指定table的 text code 获取字典值text + * dictTableCache采用redis缓存有效期10分钟 + * + * @param table + * @param text + * @param code + * @param key + * @return + */ + @Override + @Cacheable(value = CacheConstant.SYS_DICT_TABLE_CACHE, unless = "#result == null ") + public String queryTableDictTextByKey(String table, String text, String code, String key) { + log.debug("无缓存dictTable的时候调用这里!"); + return sysDictMapper.queryTableDictTextByKey(table, text, code, key); + } + + @Override + public List queryTableDictTextByKeys(String table, String text, String code, List keys) { + //update-begin-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件 + String filterSql = null; + if (table.toLowerCase().indexOf("where") > 0) { + String[] arr = table.split(" (?i)where "); + table = arr[0]; + filterSql = arr[1]; + } + return sysDictMapper.queryTableDictByKeysAndFilterSql(table, text, code, filterSql, keys); + //update-end-author:taoyan date:20220113 for: @dict注解支持 dicttable 设置where条件 + } + + @Override + public List queryTableDictByKeys(String table, String text, String code, String keys) { + return this.queryTableDictByKeys(table, text, code, keys, true); + } + + /** + * 通过查询指定table的 text code 获取字典,包含text和value + * dictTableCache采用redis缓存有效期10分钟 + * + * @param table + * @param text + * @param code + * @param keys (逗号分隔) + * @param delNotExist 是否移除不存在的项,默认为true,设为false如果某个key不存在数据库中,则直接返回key本身 + * @return + */ + @Override + //update-begin--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存 + //@Cacheable(value = CacheConstant.SYS_DICT_TABLE_BY_KEYS_CACHE) + //update-end--Author:lvdandan Date:20201204 for:JT-36【online】树形列表bug修改后,还是显示原来值 暂时去掉缓存 + public List queryTableDictByKeys(String table, String text, String code, String keys, boolean delNotExist) { + if (oConvertUtils.isEmpty(keys)) { + return null; + } + String[] keyArray = keys.split(","); + List dicts = sysDictMapper.queryTableDictByKeys(table, text, code, keyArray); + List texts = new ArrayList<>(dicts.size()); + + // update-begin--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ---- + // 查询出来的顺序可能是乱的,需要排个序 + for (String key : keyArray) { + List res = dicts.stream().filter(i -> key.equals(i.getValue())).collect(Collectors.toList()); + if (res.size() > 0) { + texts.add(res.get(0).getText()); + } else if (!delNotExist) { + texts.add(key); + } + } + // update-end--author:sunjianlei--date:20210514--for:新增delNotExist参数,设为false不删除数据库里不存在的key ---- + + return texts; + } + + /** + * 根据字典类型id删除关联表中其对应的数据 + */ + @Override + public boolean deleteByDictId(SysDict sysDict) { + sysDict.setDelFlag(CommonConstant.DEL_FLAG_1); + return this.updateById(sysDict); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Integer saveMain(SysDict sysDict, List sysDictItemList) { + int insert = 0; + try { + insert = sysDictMapper.insert(sysDict); + if (sysDictItemList != null) { + for (SysDictItem entity : sysDictItemList) { + //update-begin---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------ + if (oConvertUtils.isEmpty(entity.getItemValue())) { + return -1; + } + //update-end---author:wangshuai ---date:20220211 for:[JTC-1168]如果字典项值为空,则字典项忽略导入------------ + entity.setDictId(sysDict.getId()); + entity.setStatus(1); + sysDictItemMapper.insert(entity); + } + } + } catch (Exception e) { + return insert; + } + return insert; + } + + @Override + public List queryAllDepartBackDictModel() { + return baseMapper.queryAllDepartBackDictModel(); + } + + @Override + public List queryAllUserBackDictModel() { + return baseMapper.queryAllUserBackDictModel(); + } + + @Override + public List queryTableDictItems(String table, String text, String code, String keyword) { + return baseMapper.queryTableDictItems(table, text, code, "%" + keyword + "%"); + } + + @Override + public List queryLittleTableDictItems(String table, String text, String code, String condition, String keyword, int pageSize) { + Page page = new Page(1, pageSize); + page.setSearchCount(false); + String filterSql = getFilterSql(table, text, code, condition, keyword); + IPage pageList = baseMapper.queryTableDictWithFilter(page, table, text, code, filterSql); + return pageList.getRecords(); + } + + /** + * 获取条件语句 + * + * @param text + * @param code + * @param condition + * @param keyword + * @return + */ + private String getFilterSql(String table, String text, String code, String condition, String keyword) { + String keywordSql = null, filterSql = "", sql_where = " where "; + // update-begin-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错 + if (table.toLowerCase().contains(" where ")) { + sql_where = " and "; + } + // update-end-author:sunjianlei date:20220112 for: 【JTC-631】判断如果 table 携带了 where 条件,那么就使用 and 查询,防止报错 + if (oConvertUtils.isNotEmpty(keyword)) { + // 判断是否是多选 + if (keyword.contains(",")) { + //update-begin--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致 ---- + String inKeywords = "'" + String.join("','", keyword.split(",")) + "'"; + //update-end--author:scott--date:20220105--for:JTC-529【表单设计器】 编辑页面报错,in参数采用双引号导致---- + keywordSql = "(" + text + " in (" + inKeywords + ") or " + code + " in (" + inKeywords + "))"; + } else { + keywordSql = "(" + text + " like '%" + keyword + "%' or " + code + " like '%" + keyword + "%')"; + } + } + if (oConvertUtils.isNotEmpty(condition) && oConvertUtils.isNotEmpty(keywordSql)) { + filterSql += sql_where + condition + " and " + keywordSql; + } else if (oConvertUtils.isNotEmpty(condition)) { + filterSql += sql_where + condition; + } else if (oConvertUtils.isNotEmpty(keywordSql)) { + filterSql += sql_where + keywordSql; + } + return filterSql; + } + + @Override + public List queryAllTableDictItems(String table, String text, String code, String condition, String keyword) { + String filterSql = getFilterSql(table, text, code, condition, keyword); + List ls = baseMapper.queryAllTableDictItems(table, text, code, filterSql); + return ls; + } + + @Override + public List queryTreeList(Map query, String table, String text, String code, String pidField, String pid, String hasChildField) { + List result = baseMapper.queryTreeList(query, table, text, code, pidField, pid, hasChildField); + // udapte-begin-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点 +// if (query != null) { +// result.forEach(r -> r.setLeaf(true)); +// } + return result; + // udapte-end-author:sunjianlei date:20220110 for: 【JTC-597】如果 query 有值,就不允许展开子节点 + } + + @Override + public void deleteOneDictPhysically(String id) { + this.baseMapper.deleteOneById(id); + this.sysDictItemMapper.delete(new LambdaQueryWrapper().eq(SysDictItem::getDictId, id)); + } + + @Override + public void updateDictDelFlag(int delFlag, String id) { + baseMapper.updateDictDelFlag(delFlag, id); + } + + @Override + public List queryDeleteList() { + return baseMapper.queryDeleteList(); + } + + @Override + public List queryDictTablePageList(DictQuery query, int pageSize, int pageNo) { + Page page = new Page(pageNo, pageSize, false); + Page pageList = baseMapper.queryDictTablePageList(page, query); + return pageList.getRecords(); + } + + @Override + public List getDictItems(String dictCode) { + List ls = null; + if (dictCode.contains(",")) { + //关联表字典(举例:sys_user,realname,id) + String[] params = dictCode.split(","); + if (params.length < 3) { + // 字典Code格式不正确 + return null; + } + //SQL注入校验(只限制非法串改数据库) + final String[] sqlInjCheck = {params[0], params[1], params[2]}; + SqlInjectionUtil.filterContent(sqlInjCheck); + if (params.length == 4) { + // SQL注入校验(查询条件SQL 特殊check,此方法仅供此处使用) + SqlInjectionUtil.specialFilterContent(params[3]); + ls = this.queryTableDictItemsByCodeAndFilter(params[0], params[1], params[2], params[3]); + } else if (params.length == 3) { + ls = this.queryTableDictItemsByCode(params[0], params[1], params[2]); + } else { + // 字典Code格式不正确 + return null; + } + } else { + //判断是不是区域表 + if (DictConstants.FRONT_DICT_SMCP_AREA.equals(dictCode)){ + log.info("=============区域字典开始查询============="); +// ls = this.queryAreaItemsByCode(dictCode); +// log.info("=============区域字典查询============="+ls); + }else { + //字典表 + ls = this.queryDictItemsByCode(dictCode); + } + } + return ls; + } + +// private List queryAreaItemsByCode(String dictCode) { +// LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); +// List ls = null; +// if (RoleConstant.AREA_ADMIN_ROLE_ID.equals(loginUser.getRoleId())) { +// //区域管理员 +// List areaIdList = loginUser.getAreaIdList(); +// if (areaIdList != null || areaIdList.size()==0) { +// ls = sysDictMapper.queryAreaItemsByCode(dictCode, areaIdList); +// } +// } else if (RoleConstant.SYS_ADMIN_ROLE_ID.equals(loginUser.getRoleId()) || RoleConstant.SUPER_ADMIN_ROLE_ID.equals(loginUser.getRoleId())) { +// //系统管理员 +// ls = this.queryTableDictItemsByCode("smcp_area where area_id='0'", "name", "id"); +// } +// return ls; +// } + + @Override + public List loadDict(String dictCode, String keyword, Integer pageSize) { + if (dictCode.contains(",")) { + //update-begin-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件 + String[] params = dictCode.split(","); + String condition = null; + if (params.length != 3 && params.length != 4) { + // 字典Code格式不正确 + return null; + } else if (params.length == 4) { + condition = params[3]; + // update-begin-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500 + if (condition.indexOf("#{") >= 0) { + condition = QueryGenerator.getSqlRuleValue(condition); + } + // update-end-author:taoyan date:20220314 for: online表单下拉搜索框表字典配置#{sys_org_code}报错 #3500 + } + List ls; + if (pageSize != null) { + ls = this.queryLittleTableDictItems(params[0], params[1], params[2], condition, keyword, pageSize); + } else { + ls = this.queryAllTableDictItems(params[0], params[1], params[2], condition, keyword); + } + //update-end-author:taoyan date:20210329 for: 下拉搜索不支持表名后加查询条件 + return ls; + } else { + // 字典Code格式不正确 + return null; + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysFillRuleServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysFillRuleServiceImpl.java new file mode 100644 index 0000000..185e953 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysFillRuleServiceImpl.java @@ -0,0 +1,18 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysFillRule; +import digital.system.jeecg.system.mapper.SysFillRuleMapper; +import digital.system.jeecg.system.service.ISysFillRuleService; + +/** + * @Description: 填值规则 + * @Author: zita + * @Date: 2019-11-07 + * @Version: V1.0 + */ +@Service("sysFillRuleServiceImpl") +public class SysFillRuleServiceImpl extends ServiceImpl implements ISysFillRuleService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysGatewayRouteServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysGatewayRouteServiceImpl.java new file mode 100644 index 0000000..b6e76f2 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysGatewayRouteServiceImpl.java @@ -0,0 +1,109 @@ +//package digital.system.jeecg.system.service.impl; +// +//import cn.hutool.core.util.ObjectUtil; +//import com.alibaba.fastjson.JSON; +//import com.alibaba.fastjson.JSONObject; +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.data.redis.core.RedisTemplate; +//import org.springframework.stereotype.Service; +//import org.springframework.transaction.annotation.Transactional; +//import digital.base.constant.CacheConstant; +//import digital.base.constant.GlobalConstants; +//import digital.bean.jeecg.BaseMap; +//import digital.system.jeecg.system.entity.SysGatewayRoute; +//import digital.system.jeecg.system.mapper.SysGatewayRouteMapper; +//import digital.system.jeecg.system.service.ISysGatewayRouteService; +//import digital.util.util.oConvertUtils; +// +//import java.util.List; +// +///** +// * @Description: gateway路由管理 +// * @Author: zita +// * @Date: 2020-05-26 +// * @Version: V1.0 +// */ +//@Service +//@Slf4j +//public class SysGatewayRouteServiceImpl extends ServiceImpl implements ISysGatewayRouteService { +// +// @Autowired +// private RedisTemplate redisTemplate; +// +// +// @Override +// public void addRoute2Redis(String key) { +// List ls = this.list(new LambdaQueryWrapper()); +// redisTemplate.opsForValue().set(key, JSON.toJSONString(ls)); +// } +// +// @Override +// public void deleteById(String id) { +// this.removeById(id); +// this.resreshRouter(id); +// } +// +// @Override +// @Transactional(rollbackFor = Exception.class) +// public void updateAll(JSONObject json) { +// log.info("--gateway 路由配置修改--"); +// try { +// json = json.getJSONObject("router"); +// String id = json.getString("id"); +// //update-begin-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J +// SysGatewayRoute route; +// if (oConvertUtils.isEmpty(id)) { +// route = new SysGatewayRoute(); +// } else { +// route = getById(id); +// } +// //update-end-author:taoyan date:20211025 for: oracle路由网关新增小bug /issues/I4EV2J +// if (ObjectUtil.isEmpty(route)) { +// route = new SysGatewayRoute(); +// } +// route.setRouterId(json.getString("routerId")); +// route.setName(json.getString("name")); +// route.setPredicates(json.getString("predicates")); +// String filters = json.getString("filters"); +// if (ObjectUtil.isEmpty(filters)) { +// filters = "[]"; +// } +// route.setFilters(filters); +// route.setUri(json.getString("uri")); +// if (json.get("status") == null) { +// route.setStatus(1); +// } else { +// route.setStatus(json.getInteger("status")); +// } +// this.saveOrUpdate(route); +// resreshRouter(null); +// } catch (Exception e) { +// log.error("路由配置解析失败", e); +// resreshRouter(null); +// e.printStackTrace(); +// } +// } +// +// /** +// * 更新redis路由缓存 +// */ +// private void resreshRouter(String delRouterId) { +// //更新redis路由缓存 +// addRoute2Redis(CacheConstant.GATEWAY_ROUTES); +// BaseMap params = new BaseMap(); +// params.put(GlobalConstants.HANDLER_NAME, GlobalConstants.LODER_ROUDER_HANDLER); +// params.put("delRouterId", delRouterId); +// //刷新网关 +// redisTemplate.convertAndSend(GlobalConstants.REDIS_TOPIC_NAME, params); +// } +// +// @Override +// public void clearRedis() { +// redisTemplate.opsForValue().set(CacheConstant.GATEWAY_ROUTES, null); +// } +// +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysLogServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysLogServiceImpl.java new file mode 100644 index 0000000..55f5b11 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysLogServiceImpl.java @@ -0,0 +1,63 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysLog; +import digital.system.jeecg.system.mapper.SysLogMapper; +import digital.system.jeecg.system.service.ISysLogService; +import digital.util.util.CommonUtils; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + *

+ * 系统日志表 服务实现类 + *

+ * + * @Author zhangweijian + * @since 2018-12-26 + */ +@Service +public class SysLogServiceImpl extends ServiceImpl implements ISysLogService { + + @Resource + private SysLogMapper sysLogMapper; + @Autowired + private SysBaseApiImpl sysBaseAPI; + + /** + * @功能:清空所有日志记录 + */ + @Override + public void removeAll() { + sysLogMapper.removeAll(); + } + + @Override + public Long findTotalVisitCount() { + return sysLogMapper.findTotalVisitCount(); + } + + //update-begin--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + @Override + public Long findTodayVisitCount(Date dayStart, Date dayEnd) { + return sysLogMapper.findTodayVisitCount(dayStart, dayEnd); + } + + @Override + public Long findTodayIp(Date dayStart, Date dayEnd) { + return sysLogMapper.findTodayIp(dayStart, dayEnd); + } + //update-end--Author:zhangweijian Date:20190428 for:传入开始时间,结束时间参数 + + @Override + public List> findVisitCount(Date dayStart, Date dayEnd) { + DbType dbType = CommonUtils.getDatabaseTypeEnum(); + return sysLogMapper.findVisitCount(dayStart, dayEnd, dbType.getDb()); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionDataRuleImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionDataRuleImpl.java new file mode 100644 index 0000000..a4608cd --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionDataRuleImpl.java @@ -0,0 +1,114 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.base.constant.CommonConstant; +import digital.system.jeecg.group.query.QueryGenerator; +import digital.system.jeecg.system.entity.SysPermission; +import digital.system.jeecg.system.entity.SysPermissionDataRule; +import digital.system.jeecg.system.mapper.SysPermissionDataRuleMapper; +import digital.system.jeecg.system.mapper.SysPermissionMapper; +import digital.system.jeecg.system.service.ISysPermissionDataRuleService; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + *

+ * 菜单权限规则 服务实现类 + *

+ * + * @Author huangzhilin + * @since 2019-04-01 + */ +@Service +public class SysPermissionDataRuleImpl extends ServiceImpl + implements ISysPermissionDataRuleService { + + @Resource + private SysPermissionMapper sysPermissionMapper; + + /** + * 根据菜单id查询其对应的权限数据 + */ + @Override + public List getPermRuleListByPermId(String permissionId) { + LambdaQueryWrapper query = new LambdaQueryWrapper(); + query.eq(SysPermissionDataRule::getPermissionId, permissionId); + query.orderByDesc(SysPermissionDataRule::getCreateTime); + List permRuleList = this.list(query); + return permRuleList; + } + + /** + * 根据前端传递的权限名称和权限值参数来查询权限数据 + */ + @Override + public List queryPermissionRule(SysPermissionDataRule permRule) { + QueryWrapper queryWrapper = QueryGenerator.initQueryWrapper(permRule, null); + return this.list(queryWrapper); + } + + @Override + public List queryPermissionDataRules(String username, String permissionId) { + List idsList = this.baseMapper.queryDataRuleIds(username, permissionId); + //update-begin--Author:scott Date:20191119 for:数据权限失效问题处理-------------------- + if (idsList == null || idsList.size() == 0) { + return null; + } + //update-end--Author:scott Date:20191119 for:数据权限失效问题处理-------------------- + Set set = new HashSet(); + for (String ids : idsList) { + if (oConvertUtils.isEmpty(ids)) { + continue; + } + String[] arr = ids.split(","); + for (String id : arr) { + if (oConvertUtils.isNotEmpty(id) && !set.contains(id)) { + set.add(id); + } + } + } + if (set.size() == 0) { + return null; + } + return this.baseMapper.selectList(new QueryWrapper().in("id", set).eq("status", CommonConstant.STATUS_1)); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void savePermissionDataRule(SysPermissionDataRule sysPermissionDataRule) { + this.save(sysPermissionDataRule); + SysPermission permission = sysPermissionMapper.selectById(sysPermissionDataRule.getPermissionId()); + if (permission != null && (permission.getRuleFlag() == null || permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_0))) { + permission.setRuleFlag(CommonConstant.RULE_FLAG_1); + sysPermissionMapper.updateById(permission); + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void deletePermissionDataRule(String dataRuleId) { + SysPermissionDataRule dataRule = this.baseMapper.selectById(dataRuleId); + if (dataRule != null) { + this.removeById(dataRuleId); + Long count = this.baseMapper.selectCount(new LambdaQueryWrapper().eq(SysPermissionDataRule::getPermissionId, dataRule.getPermissionId())); + //注:同一个事务中删除后再查询是会认为数据已被删除的 若事务回滚上述删除无效 + if (count == null || count == 0) { + SysPermission permission = sysPermissionMapper.selectById(dataRule.getPermissionId()); + if (permission != null && permission.getRuleFlag().equals(CommonConstant.RULE_FLAG_1)) { + permission.setRuleFlag(CommonConstant.RULE_FLAG_0); + sysPermissionMapper.updateById(permission); + } + } + } + + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionServiceImpl.java new file mode 100644 index 0000000..ac50ec7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPermissionServiceImpl.java @@ -0,0 +1,266 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import digital.base.constant.CacheConstant; +import digital.base.constant.CommonConstant; +import digital.system.jeecg.system.entity.SysPermission; +import digital.system.jeecg.system.entity.SysPermissionDataRule; +import digital.system.jeecg.system.mapper.SysDepartPermissionMapper; +import digital.system.jeecg.system.mapper.SysDepartRolePermissionMapper; +import digital.system.jeecg.system.mapper.SysPermissionMapper; +import digital.system.jeecg.system.mapper.SysRolePermissionMapper; +import digital.system.jeecg.system.model.TreeModel; +import digital.system.jeecg.system.service.ISysPermissionDataRuleService; +import digital.system.jeecg.system.service.ISysPermissionService; +import digital.util.exception.JeecgBootException; +import digital.util.util.oConvertUtils; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

+ * 菜单权限表 服务实现类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Service +public class SysPermissionServiceImpl extends ServiceImpl implements ISysPermissionService { + + @Resource + private SysPermissionMapper sysPermissionMapper; + + @Resource + private ISysPermissionDataRuleService permissionDataRuleService; + + @Resource + private SysRolePermissionMapper sysRolePermissionMapper; + + @Resource + private SysDepartPermissionMapper sysDepartPermissionMapper; + + @Resource + private SysDepartRolePermissionMapper sysDepartRolePermissionMapper; + + @Override + public List queryListByParentId(String parentId) { + return sysPermissionMapper.queryListByParentId(parentId); + } + + /** + * 真实删除 + */ + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE, allEntries = true) + public void deletePermission(String id) throws JeecgBootException { + SysPermission sysPermission = this.getById(id); + if (sysPermission == null) { + throw new JeecgBootException("未找到菜单信息"); + } + String pid = sysPermission.getParentId(); + if (oConvertUtils.isNotEmpty(pid)) { + Long count = this.count(new QueryWrapper().lambda().eq(SysPermission::getParentId, pid)); + if (count == 1) { + //若父节点无其他子节点,则该父节点是叶子节点 + this.sysPermissionMapper.setMenuLeaf(pid, 1); + } + } + sysPermissionMapper.deleteById(id); + // 该节点可能是子节点但也可能是其它节点的父节点,所以需要级联删除 + this.removeChildrenBy(sysPermission.getId()); + //关联删除 + Map map = new HashMap(5); + map.put("permission_id", id); + //删除数据规则 + this.deletePermRuleByPermId(id); + //删除角色授权表 + sysRolePermissionMapper.deleteByMap(map); + //删除部门权限表 + sysDepartPermissionMapper.deleteByMap(map); + //删除部门角色授权 + sysDepartRolePermissionMapper.deleteByMap(map); + } + + /** + * 根据父id删除其关联的子节点数据 + * + * @return + */ + public void removeChildrenBy(String parentId) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + // 封装查询条件parentId为主键, + query.eq(SysPermission::getParentId, parentId); + // 查出该主键下的所有子级 + List permissionList = this.list(query); + if (permissionList != null && permissionList.size() > 0) { + // id + String id = ""; + // 查出的子级数量 + Long num = Long.valueOf(0); + // 如果查出的集合不为空, 则先删除所有 + this.remove(query); + // 再遍历刚才查出的集合, 根据每个对象,查找其是否仍有子级 + for (int i = 0, len = permissionList.size(); i < len; i++) { + id = permissionList.get(i).getId(); + Map map = new HashMap(5); + map.put("permission_id", id); + //删除数据规则 + this.deletePermRuleByPermId(id); + //删除角色授权表 + sysRolePermissionMapper.deleteByMap(map); + //删除部门权限表 + sysDepartPermissionMapper.deleteByMap(map); + //删除部门角色授权 + sysDepartRolePermissionMapper.deleteByMap(map); + num = this.count(new LambdaQueryWrapper().eq(SysPermission::getParentId, id)); + // 如果有, 则递归 + if (num > 0) { + this.removeChildrenBy(id); + } + } + } + } + + /** + * 逻辑删除 + */ + @Override + @CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE, allEntries = true) + //@CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE,allEntries=true,condition="#sysPermission.menuType==2") + public void deletePermissionLogical(String id) throws JeecgBootException { + SysPermission sysPermission = this.getById(id); + if (sysPermission == null) { + throw new JeecgBootException("未找到菜单信息"); + } + String pid = sysPermission.getParentId(); + Long count = this.count(new QueryWrapper().lambda().eq(SysPermission::getParentId, pid)); + if (count == 1) { + //若父节点无其他子节点,则该父节点是叶子节点 + this.sysPermissionMapper.setMenuLeaf(pid, 1); + } + sysPermission.setDelFlag(1); + this.updateById(sysPermission); + } + + @Override + @CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE, allEntries = true) + public void addPermission(SysPermission sysPermission) throws JeecgBootException { + //---------------------------------------------------------------------- + //判断是否是一级菜单,是的话清空父菜单 + if (CommonConstant.MENU_TYPE_0.equals(sysPermission.getMenuType())) { + sysPermission.setParentId(null); + } + //---------------------------------------------------------------------- + String pid = sysPermission.getParentId(); + if (oConvertUtils.isNotEmpty(pid)) { + //设置父节点不为叶子节点 + this.sysPermissionMapper.setMenuLeaf(pid, 0); + } + sysPermission.setCreateTime(new Date()); + sysPermission.setDelFlag(0); + sysPermission.setLeaf(true); + this.save(sysPermission); + } + + @Override + @CacheEvict(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE, allEntries = true) + public void editPermission(SysPermission sysPermission) throws JeecgBootException { + SysPermission p = this.getById(sysPermission.getId()); + //TODO 该节点判断是否还有子节点 + if (p == null) { + throw new JeecgBootException("未找到菜单信息"); + } else { + sysPermission.setUpdateTime(new Date()); + //---------------------------------------------------------------------- + //Step1.判断是否是一级菜单,是的话清空父菜单ID + if (CommonConstant.MENU_TYPE_0.equals(sysPermission.getMenuType())) { + sysPermission.setParentId(""); + } + //Step2.判断菜单下级是否有菜单,无则设置为叶子节点 + Long count = this.count(new QueryWrapper().lambda().eq(SysPermission::getParentId, sysPermission.getId())); + if (count == 0) { + sysPermission.setLeaf(true); + } + //---------------------------------------------------------------------- + this.updateById(sysPermission); + + //如果当前菜单的父菜单变了,则需要修改新父菜单和老父菜单的,叶子节点状态 + String pid = sysPermission.getParentId(); + if ((oConvertUtils.isNotEmpty(pid) && !pid.equals(p.getParentId())) || oConvertUtils.isEmpty(pid) && oConvertUtils.isNotEmpty(p.getParentId())) { + //a.设置新的父菜单不为叶子节点 + this.sysPermissionMapper.setMenuLeaf(pid, 0); + //b.判断老的菜单下是否还有其他子菜单,没有的话则设置为叶子节点 + Long cc = this.count(new QueryWrapper().lambda().eq(SysPermission::getParentId, p.getParentId())); + if (cc == 0) { + if (oConvertUtils.isNotEmpty(p.getParentId())) { + this.sysPermissionMapper.setMenuLeaf(p.getParentId(), 1); + } + } + + } + } + + } + + @Override + public List queryByUser(String username) { + return this.sysPermissionMapper.queryByUser(username); + } + + /** + * 根据permissionId删除其关联的SysPermissionDataRule表中的数据 + */ + @Override + public void deletePermRuleByPermId(String id) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + query.eq(SysPermissionDataRule::getPermissionId, id); + Long countValue = this.permissionDataRuleService.count(query); + if (countValue > 0) { + this.permissionDataRuleService.remove(query); + } + } + + /** + * 获取模糊匹配规则的数据权限URL + */ + @Override + @Cacheable(value = CacheConstant.SYS_DATA_PERMISSIONS_CACHE) + public List queryPermissionUrlWithStar() { + return this.baseMapper.queryPermissionUrlWithStar(); + } + + @Override + public boolean hasPermission(String username, SysPermission sysPermission) { + int count = baseMapper.queryCountByUsername(username, sysPermission); + if (count > 0) { + return true; + } else { + return false; + } + } + + @Override + public boolean hasPermission(String username, String url) { + SysPermission sysPermission = new SysPermission(); + sysPermission.setUrl(url); + int count = baseMapper.queryCountByUsername(username, sysPermission); + if (count > 0) { + return true; + } else { + return false; + } + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPositionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPositionServiceImpl.java new file mode 100644 index 0000000..7354341 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysPositionServiceImpl.java @@ -0,0 +1,26 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysPosition; +import digital.system.jeecg.system.mapper.SysPositionMapper; +import digital.system.jeecg.system.service.ISysPositionService; + +/** + * @Description: 职务表 + * @Author: zita + * @Date: 2019-09-19 + * @Version: V1.0 + */ +@Service +public class SysPositionServiceImpl extends ServiceImpl implements ISysPositionService { + + @Override + public SysPosition getByCode(String code) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(SysPosition::getCode, code); + return super.getOne(queryWrapper); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleIndexServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleIndexServiceImpl.java new file mode 100644 index 0000000..7a7acff --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleIndexServiceImpl.java @@ -0,0 +1,18 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysRoleIndex; +import digital.system.jeecg.system.mapper.SysRoleIndexMapper; +import digital.system.jeecg.system.service.ISysRoleIndexService; + +/** + * @Description: 角色首页配置 + * @Author: zita + * @Date: 2022-03-25 + * @Version: V1.0 + */ +@Service +public class SysRoleIndexServiceImpl extends ServiceImpl implements ISysRoleIndexService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRolePermissionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRolePermissionServiceImpl.java new file mode 100644 index 0000000..e7e76b0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRolePermissionServiceImpl.java @@ -0,0 +1,117 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysRolePermission; +import digital.system.jeecg.system.mapper.SysRolePermissionMapper; +import digital.system.jeecg.system.service.ISysRolePermissionService; +import digital.util.util.IpUtils; +import digital.util.util.SpringContextUtils; +import digital.util.util.oConvertUtils; + +import javax.servlet.http.HttpServletRequest; +import java.util.*; + +/** + *

+ * 角色权限表 服务实现类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Service +public class SysRolePermissionServiceImpl extends ServiceImpl implements ISysRolePermissionService { + + @Override + public void saveRolePermission(String roleId, String permissionIds) { + String ip = ""; + try { + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //获取IP地址 + ip = IpUtils.getIpAddr(request); + } catch (Exception e) { + ip = "127.0.0.1"; + } + LambdaQueryWrapper query = new QueryWrapper().lambda().eq(SysRolePermission::getRoleId, roleId); + this.remove(query); + List list = new ArrayList(); + String[] arr = permissionIds.split(","); + for (String p : arr) { + if (oConvertUtils.isNotEmpty(p)) { + SysRolePermission rolepms = new SysRolePermission(roleId, p); + rolepms.setOperateDate(new Date()); + rolepms.setOperateIp(ip); + list.add(rolepms); + } + } + this.saveBatch(list); + } + + @Override + public void saveRolePermission(String roleId, String permissionIds, String lastPermissionIds) { + String ip = ""; + try { + //获取request + HttpServletRequest request = SpringContextUtils.getHttpServletRequest(); + //获取IP地址 + ip = IpUtils.getIpAddr(request); + } catch (Exception e) { + ip = "127.0.0.1"; + } + List add = getDiff(lastPermissionIds, permissionIds); + if (add != null && add.size() > 0) { + List list = new ArrayList(); + for (String p : add) { + if (oConvertUtils.isNotEmpty(p)) { + SysRolePermission rolepms = new SysRolePermission(roleId, p); + rolepms.setOperateDate(new Date()); + rolepms.setOperateIp(ip); + list.add(rolepms); + } + } + this.saveBatch(list); + } + + List delete = getDiff(permissionIds, lastPermissionIds); + if (delete != null && delete.size() > 0) { + for (String permissionId : delete) { + this.remove(new QueryWrapper().lambda().eq(SysRolePermission::getRoleId, roleId).eq(SysRolePermission::getPermissionId, permissionId)); + } + } + } + + /** + * 从diff中找出main中没有的元素 + * + * @param main + * @param diff + * @return + */ + private List getDiff(String main, String diff) { + if (oConvertUtils.isEmpty(diff)) { + return null; + } + if (oConvertUtils.isEmpty(main)) { + return Arrays.asList(diff.split(",")); + } + + String[] mainArr = main.split(","); + String[] diffArr = diff.split(","); + Map map = new HashMap(5); + for (String string : mainArr) { + map.put(string, 1); + } + List res = new ArrayList(); + for (String key : diffArr) { + if (oConvertUtils.isNotEmpty(key) && !map.containsKey(key)) { + res.add(key); + } + } + return res; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleServiceImpl.java new file mode 100644 index 0000000..45079dd --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysRoleServiceImpl.java @@ -0,0 +1,88 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.jeecgframework.poi.excel.ExcelImportUtil; +import org.jeecgframework.poi.excel.entity.ImportParams; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import digital.base.constant.CommonConstant; +import digital.base.vo.Result; +import digital.system.jeecg.system.entity.SysRole; +import digital.system.jeecg.system.mapper.SysRoleMapper; +import digital.system.jeecg.system.mapper.SysUserMapper; +import digital.system.jeecg.system.service.ISysRoleService; +import digital.util.util.ImportExcelUtil; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + *

+ * 角色表 服务实现类 + *

+ * + * @Author scott + * @since 2018-12-19 + */ +@Service +public class SysRoleServiceImpl extends ServiceImpl implements ISysRoleService { + @Autowired + SysRoleMapper sysRoleMapper; + @Autowired + SysUserMapper sysUserMapper; + + @Override + public Result importExcelCheckRoleCode(MultipartFile file, ImportParams params) throws Exception { + List listSysRoles = ExcelImportUtil.importExcel(file.getInputStream(), SysRole.class, params); + int totalCount = listSysRoles.size(); + List errorStrs = new ArrayList<>(); + + // 去除 listSysRoles 中重复的数据 + for (int i = 0; i < listSysRoles.size(); i++) { + String roleCodeI = ((SysRole) listSysRoles.get(i)).getRoleCode(); + for (int j = i + 1; j < listSysRoles.size(); j++) { + String roleCodeJ = ((SysRole) listSysRoles.get(j)).getRoleCode(); + // 发现重复数据 + if (roleCodeI.equals(roleCodeJ)) { + errorStrs.add("第 " + (j + 1) + " 行的 roleCode 值:" + roleCodeI + " 已存在,忽略导入"); + listSysRoles.remove(j); + break; + } + } + } + // 去掉 sql 中的重复数据 + Integer errorLines = 0; + Integer successLines = 0; + List list = ImportExcelUtil.importDateSave(listSysRoles, ISysRoleService.class, errorStrs, CommonConstant.SQL_INDEX_UNIQ_SYS_ROLE_CODE); + errorLines += list.size(); + successLines += (listSysRoles.size() - errorLines); + return ImportExcelUtil.imporReturnRes(errorLines, successLines, list); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean deleteRole(String roleid) { + //1.删除角色和用户关系 + sysRoleMapper.deleteRoleUserRelation(roleid); + //2.删除角色和权限关系 + sysRoleMapper.deleteRolePermissionRelation(roleid); + //3.删除角色 + this.removeById(roleid); + return true; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean deleteBatchRole(String[] roleIds) { + //1.删除角色和用户关系 + sysUserMapper.deleteBathRoleUserRelation(roleIds); + //2.删除角色和权限关系 + sysUserMapper.deleteBathRolePermissionRelation(roleIds); + //3.删除角色 + this.removeByIds(Arrays.asList(roleIds)); + return true; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysTenantServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysTenantServiceImpl.java new file mode 100644 index 0000000..c11b438 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysTenantServiceImpl.java @@ -0,0 +1,60 @@ +//package digital.system.jeecg.system.service.impl; +// +//import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import lombok.extern.slf4j.Slf4j; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Service; +//import digital.base.constant.CommonConstant; +//import digital.system.jeecg.system.entity.SysTenant; +//import digital.system.jeecg.system.entity.SysUser; +//import digital.system.jeecg.system.mapper.SysTenantMapper; +//import digital.system.jeecg.system.service.ISysTenantService; +//import digital.system.jeecg.system.service.ISysUserService; +//import digital.util.exception.JeecgBootException; +// +//import java.util.Collection; +//import java.util.List; +// +///** +// * @Description: 租户实现类 +// * @author: smcp +// */ +//@Service("sysTenantServiceImpl") +//@Slf4j +//public class SysTenantServiceImpl extends ServiceImpl implements ISysTenantService { +// +// @Autowired +// ISysUserService userService; +// +// @Override +// public List queryEffectiveTenant(Collection idList) { +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.in(SysTenant::getId, idList); +// queryWrapper.eq(SysTenant::getStatus, Integer.valueOf(CommonConstant.STATUS_1)); +// //此处查询忽略时间条件 +// return super.list(queryWrapper); +// } +// +// @Override +// public Long countUserLinkTenant(String id) { +// LambdaQueryWrapper userQueryWrapper = new LambdaQueryWrapper<>(); +//// userQueryWrapper.eq(SysUser::getRelTenantIds, id); +//// userQueryWrapper.or().like(SysUser::getRelTenantIds, "%," + id); +//// userQueryWrapper.or().like(SysUser::getRelTenantIds, id + ",%"); +//// userQueryWrapper.or().like(SysUser::getRelTenantIds, "%," + id + ",%"); +// // 查找出已被关联的用户数量 +// return userService.count(userQueryWrapper); +// } +// +// @Override +// public boolean removeTenantById(String id) { +// // 查找出已被关联的用户数量 +// Long userCount = this.countUserLinkTenant(id); +// if (userCount > 0) { +// throw new JeecgBootException("该租户已被引用,无法删除!"); +// } +// return super.removeById(Integer.parseInt(id)); +// } +// +//} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserAgentServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserAgentServiceImpl.java new file mode 100644 index 0000000..7eacafe --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserAgentServiceImpl.java @@ -0,0 +1,18 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysUserAgent; +import digital.system.jeecg.system.mapper.SysUserAgentMapper; +import digital.system.jeecg.system.service.ISysUserAgentService; + +/** + * @Description: 用户代理人设置 + * @Author: digital + * @Date: 2019-04-17 + * @Version: V1.0 + */ +@Service +public class SysUserAgentServiceImpl extends ServiceImpl implements ISysUserAgentService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserDepartServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserDepartServiceImpl.java new file mode 100644 index 0000000..de42a9c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserDepartServiceImpl.java @@ -0,0 +1,184 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.base.constant.CommonConstant; +import digital.system.jeecg.system.entity.SysDepart; +import digital.system.jeecg.system.entity.SysUser; +import digital.system.jeecg.system.entity.SysUserDepart; +import digital.system.jeecg.system.mapper.SysUserDepartMapper; +import digital.system.jeecg.system.mapper.SysUserMapper; +import digital.system.jeecg.system.model.DepartIdModel; +import digital.system.jeecg.system.service.ISysDepartService; +import digital.system.jeecg.system.service.ISysUserDepartService; +import digital.system.jeecg.system.vo.SysUserDepVo; +import digital.util.util.oConvertUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + *

+ * 用户部门表实现类 + *

+ * + * @Author ZhiLin + * @since 2019-02-22 + */ +@Service +public class SysUserDepartServiceImpl extends ServiceImpl implements ISysUserDepartService { + @Autowired + private ISysDepartService sysDepartService; + @Autowired + private SysUserMapper sysUserMapper; + + + /** + * 根据用户id查询部门信息 + */ + @Override + public List queryDepartIdsOfUser(String userId) { + LambdaQueryWrapper queryUDep = new LambdaQueryWrapper(); + LambdaQueryWrapper queryDep = new LambdaQueryWrapper(); + try { + queryUDep.eq(SysUserDepart::getUserId, userId); + List depIdList = new ArrayList<>(); + List depIdModelList = new ArrayList<>(); + List userDepList = this.list(queryUDep); + if (userDepList != null && userDepList.size() > 0) { + for (SysUserDepart userDepart : userDepList) { + depIdList.add(userDepart.getDepId()); + } + queryDep.in(SysDepart::getId, depIdList); + List depList = sysDepartService.list(queryDep); + if (depList != null || depList.size() > 0) { + for (SysDepart depart : depList) { + depIdModelList.add(new DepartIdModel().convertByUserDepart(depart)); + } + } + return depIdModelList; + } + } catch (Exception e) { + e.fillInStackTrace(); + } + return null; + + + } + + + /** + * 根据部门id查询用户信息 + */ + @Override + public List queryUserByDepId(String depId) { + LambdaQueryWrapper queryUDep = new LambdaQueryWrapper(); + queryUDep.eq(SysUserDepart::getDepId, depId); + List userIdList = new ArrayList<>(); + List uDepList = this.list(queryUDep); + if (uDepList != null && uDepList.size() > 0) { + for (SysUserDepart uDep : uDepList) { + userIdList.add(uDep.getUserId()); + } + List userList = (List) sysUserMapper.selectBatchIds(userIdList); + //update-begin-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息 + for (SysUser sysUser : userList) { + sysUser.setSalt(""); + sysUser.setPassword(""); + } + //update-end-author:taoyan date:201905047 for:接口调用查询返回结果不能返回密码相关信息 + return userList; + } + return new ArrayList(); + } + + /** + * 根据部门code,查询当前部门和下级部门的 用户信息 + */ + @Override + public List queryUserByDepCode(String depCode, String realname) { + //update-begin-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化 + if (oConvertUtils.isNotEmpty(realname)) { + realname = realname.trim(); + } + List userList = this.baseMapper.queryDepartUserList(depCode, realname); + Map map = new HashMap(5); + for (SysUser sysUser : userList) { + // 返回的用户数据去掉密码信息 + sysUser.setSalt(""); + sysUser.setPassword(""); +// map.put(sysUser.getId(), sysUser); + } + return new ArrayList(map.values()); + //update-end-author:taoyan date:20210422 for: 根据部门选择用户接口代码优化 + + } + + @Override + public IPage queryDepartUserPageList(String departId, String username, String realname, int pageSize, int pageNo) { + IPage pageList = null; + // 部门ID不存在 直接查询用户表即可 + Page page = new Page(pageNo, pageSize); + if (oConvertUtils.isEmpty(departId)) { + LambdaQueryWrapper query = new LambdaQueryWrapper<>(); + //update-begin---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------ + query.eq(SysUser::getStatus, Integer.parseInt(CommonConstant.STATUS_1)); + //update-end---author:wangshuai ---date:20220104 for:[JTC-297]已冻结用户仍可设置为代理人------------ + if (oConvertUtils.isNotEmpty(username)) { + query.like(SysUser::getUsername, username); + } + pageList = sysUserMapper.selectPage(page, query); + } else { + // 有部门ID 需要走自定义sql + SysDepart sysDepart = sysDepartService.getById(departId); + pageList = this.baseMapper.queryDepartUserPageList(page, sysDepart.getOrgCode(), username, realname); + } + List userList = pageList.getRecords(); + if (userList != null && userList.size() > 0) { +// List userIds = userList.stream().map(SysUser::getId).collect(Collectors.toList()); + Map map = new HashMap(5); +// if (userIds != null && userIds.size() > 0) { +// // 查部门名称 +// Map useDepNames = this.getDepNamesByUserIds(userIds); +// userList.forEach(item -> { +// //TODO 临时借用这个字段用于页面展示 +//// item.setOrgCodeTxt(useDepNames.get(item.getId())); +// item.setSalt(""); +// item.setPassword(""); +// // 去重 +// map.put(item.getId(), item); +// }); +// } + pageList.setRecords(new ArrayList(map.values())); + } + return pageList; + } + + /** + * 升级SpringBoot2.6.6,不允许循环依赖 + * + * @param userIds + * @return + */ + private Map getDepNamesByUserIds(List userIds) { + List list = sysUserMapper.getDepNamesByUserIds(userIds); + + Map res = new HashMap(5); + list.forEach(item -> { + if (res.get(item.getUserId()) == null) { + res.put(item.getUserId(), item.getDepartName()); + } else { + res.put(item.getUserId(), res.get(item.getUserId()) + "," + item.getDepartName()); + } + } + ); + return res; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserRoleServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserRoleServiceImpl.java new file mode 100644 index 0000000..a2ba267 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserRoleServiceImpl.java @@ -0,0 +1,20 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; +import digital.system.jeecg.system.entity.SysUserRole; +import digital.system.jeecg.system.mapper.SysUserRoleMapper; +import digital.system.jeecg.system.service.ISysUserRoleService; + +/** + *

+ * 用户角色表 服务实现类 + *

+ * + * @Author scott + * @since 2018-12-21 + */ +@Service +public class SysUserRoleServiceImpl extends ServiceImpl implements ISysUserRoleService { + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserServiceImpl.java new file mode 100644 index 0000000..6331659 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysUserServiceImpl.java @@ -0,0 +1,688 @@ +package digital.system.jeecg.system.service.impl; + +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import digital.base.constant.CacheConstant; +import digital.base.constant.CommonConstant; +import digital.base.constant.LanguageTypeConstants; +import digital.base.vo.Result; +import digital.system.jeecg.group.base.service.BaseCommonService; +import digital.system.jeecg.system.entity.*; +import digital.system.jeecg.system.mapper.*; +import digital.system.jeecg.system.model.SysUserSysDepartModel; +import digital.system.jeecg.system.service.ISysUserService; +import digital.system.jeecg.system.vo.SysUserDepVo; +import digital.util.util.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.annotation.CacheEvict; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.*; +import java.util.stream.Collectors; + +/** + *

+ * 用户表 服务实现类 + *

+ * + * @Author: scott + * @Date: 2018-12-20 + */ +@Service +@Slf4j +public class SysUserServiceImpl extends ServiceImpl implements ISysUserService { + + @Autowired + private SysUserMapper userMapper; +// @Autowired +// private JeecgRedisUtil jeecgRedisUtil; + @Autowired + private SysPermissionMapper sysPermissionMapper; + @Autowired + private SysUserRoleMapper sysUserRoleMapper; + @Autowired + private SysUserDepartMapper sysUserDepartMapper; + @Autowired + private SysDepartMapper sysDepartMapper; + @Autowired + private SysRoleMapper sysRoleMapper; + @Autowired + private SysDepartRoleUserMapper departRoleUserMapper; + @Autowired + private SysDepartRoleMapper sysDepartRoleMapper; + @Resource + private BaseCommonService baseCommonService; + @Autowired + private SysThirdAccountMapper sysThirdAccountMapper; +// +// @Override +// public Result loginWithDiscord(JSONObject jsonObject) { +// String discordId = jsonObject.getString("id"); +// String username = jsonObject.getString("username"); +// if (oConvertUtils.isEmpty(discordId) || oConvertUtils.isEmpty(username)) { +// return Result.error("参数错误!缺少 discordId 或者 username!"); +// } +// //未设置密码,则随机生成一个密码 +// String password = jsonObject.getString("password"); +// if (oConvertUtils.isEmpty(password)) { +// password = RandomUtil.randomString(8); +// } +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.eq(SysUser::getUsername, username); +// queryWrapper.eq(SysUser::getDiscordId, discordId); +// queryWrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0); +// SysUser sysUser = userMapper.selectOne(queryWrapper); +// if (null == sysUser) { +// //查询数据库,如果discordId或者username查询出来数据,则返回错误 +// LambdaQueryWrapper qw = new LambdaQueryWrapper<>(); +// qw.and(wrapper -> wrapper.eq(SysUser::getUsername, username).or().eq(SysUser::getDiscordId, discordId)); +// qw.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0); +// SysUser su = userMapper.selectOne(qw); +// if (su != null) { +// return Result.error("数据库中存在此username或者discordId"); +// } +// //如果没有,这说明是新用户,需要注册 新会员注册 给5次试用 +// String salt = oConvertUtils.randomGen(8); +// String passwordEncode = PasswordUtil.encrypt(username, password, salt); +// SysUser user = new SysUser(); +// user.setDiscordId(discordId); +// user.setUsername(username); +// user.setPassword(passwordEncode); +// user.setMemberExpireTime(null); +// user.setRemainNum(new BigDecimal(ZitaCommonConstant.New_register_member_try_times)); +// user.setMemberType(ZitaCommonConstant.MEMBER_TYPE_TRY_CARD); +// user.setDiscordInfo(jsonObject.toString()); +// userMapper.insert(user); +// //用户登录信息 +// String syspassword = user.getPassword(); +// String ussername = user.getUsername(); +// // 获取用户相关信息 +// JSONObject obj = new JSONObject(); +// SysUserVO sysUserVO = new SysUserVO(); +// // 生成token +// String token = JwtUtil.sign(ussername, syspassword); +// // 设置token缓存有效时间 +// jeecgRedisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); +// jeecgRedisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); +// obj.put("token", token); +// obj.put("userInfo", user); +// sysUserVO.setSysUser(user); +// sysUserVO.setToken(token); +// LoginUser loginUser = new LoginUser(); +// //BeanUtils.copyProperties(sysUser, loginUser); +// baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null, loginUser); +// return Result.OK(sysUserVO); +// } else { +// //用户登录信息 +// String syspassword = sysUser.getPassword(); +// String usessrname = sysUser.getUsername(); +// // 获取用户相关信息 +// JSONObject obj = new JSONObject(); +// SysUserVO sysUserVO = new SysUserVO(); +// // 生成token +// String token = JwtUtil.sign(usessrname, syspassword); +// // 设置token缓存有效时间 +// jeecgRedisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); +// jeecgRedisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); +// obj.put("token", token); +// obj.put("userInfo", sysUser); +// sysUserVO.setSysUser(sysUser); +// sysUserVO.setToken(token); +// LoginUser loginUser = new LoginUser(); +// //BeanUtils.copyProperties(sysUser, loginUser); +// baseCommonService.addLog("用户名: " + username + ",登录成功!", CommonConstant.LOG_TYPE_1, null, loginUser); +// return Result.OK(sysUserVO); +// } +// } + + /** + * 用户信息 + * + * @param sysUser + * @param result + * @return + */ + private Result userInfo(SysUser sysUser, Result result) { + String syspassword = sysUser.getPassword(); + String username = sysUser.getUsername(); + // 获取用户部门信息 + JSONObject obj = new JSONObject(); + // 生成token + String token = JwtUtil.sign(username, syspassword); + // 设置token缓存有效时间 +// jeecgRedisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); +// jeecgRedisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000); + obj.put("token", token); + obj.put("userInfo", sysUser); +// obj.put("sysAllDictItems", sysDictService.queryAllDictItems()); + result.setResult(obj); + result.success((LanguageTypeConstants.LANGUAGE_TYPE_LOGIN_SUCCESS)); + return result; + } + + @Override + public Result getUserTimes(String discordId) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.lambda().eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0); +// queryWrapper.lambda().eq(SysUser::getDiscordId, discordId); + SysUser user = userMapper.selectOne(queryWrapper); +// if (null != user) { +// BigDecimal remainNum = user.getRemainNum(); +// if (remainNum == null || remainNum.compareTo(BigDecimal.ZERO) <= 0) { +// log.info("The BigDecimal is either null or less than or equal to 0."); +// return Result.OK(true); +// } else { +// log.info("The BigDecimal is not null and greater than 0."); +// return Result.OK(false); +// } +// } + return Result.error("无此用户信息!"); + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + public Result resetPassword(String username, String oldpassword, String newpassword, String confirmpassword) { + SysUser user = userMapper.getUserByName(username); + String passwordEncode = PasswordUtil.encrypt(username, oldpassword, user.getSalt()); + if (!user.getPassword().equals(passwordEncode)) { + return Result.error("旧密码输入错误!"); + } + if (oConvertUtils.isEmpty(newpassword)) { + return Result.error("新密码不允许为空!"); + } + if (!newpassword.equals(confirmpassword)) { + return Result.error("两次输入密码不一致!"); + } + String password = PasswordUtil.encrypt(username, newpassword, user.getSalt()); + this.userMapper.update(new SysUser().setPassword(password), new LambdaQueryWrapper().eq(SysUser::getId, user.getId())); + return Result.ok("密码重置成功!"); + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + public Result changePassword(SysUser sysUser) { + String salt = oConvertUtils.randomGen(8); + sysUser.setSalt(salt); + String password = sysUser.getPassword(); + String passwordEncode = PasswordUtil.encrypt(sysUser.getUsername(), password, salt); + sysUser.setPassword(passwordEncode); + this.userMapper.updateById(sysUser); + return Result.ok("密码修改成功!"); + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + @Transactional(rollbackFor = Exception.class) + public boolean deleteUser(String userId) { + //1.删除用户 + this.removeById(userId); + return false; + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + @Transactional(rollbackFor = Exception.class) + public boolean deleteBatchUsers(String userIds) { + //1.删除用户 + this.removeByIds(Arrays.asList(userIds.split(","))); + return false; + } + + @Override + public SysUser getUserByName(String username) { + return userMapper.getUserByName(username); + } + + + @Override + @Transactional(rollbackFor = Exception.class) + public void addUserWithRole(SysUser user, String roles) { + this.save(user); + if (oConvertUtils.isNotEmpty(roles)) { + String[] arr = roles.split(","); + for (String roleId : arr) { +// SysUserRole userRole = new SysUserRole(user.getId(), roleId); +// sysUserRoleMapper.insert(userRole); + } + } + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + @Transactional(rollbackFor = Exception.class) + public void editUserWithRole(SysUser user, String roles) { + this.updateById(user); + //先删后加 + sysUserRoleMapper.delete(new QueryWrapper().lambda().eq(SysUserRole::getUserId, user.getId())); + if (oConvertUtils.isNotEmpty(roles)) { + String[] arr = roles.split(","); + for (String roleId : arr) { +// SysUserRole userRole = new SysUserRole(user.getId(), roleId); +// sysUserRoleMapper.insert(userRole); + } + } + } + + + @Override + public List getRole(String username) { + return sysUserRoleMapper.getRoleByUserName(username); + } + + /** + * 通过用户名获取用户角色集合 + * + * @param username 用户名 + * @return 角色集合 + */ + @Override + public Set getUserRolesSet(String username) { + // 查询用户拥有的角色集合 + List roles = sysUserRoleMapper.getRoleByUserName(username); + log.info("-------通过数据库读取用户拥有的角色Rules------username: " + username + ",Roles size: " + (roles == null ? 0 : roles.size())); + return new HashSet<>(roles); + } + + /** + * 通过用户名获取用户权限集合 + * + * @param username 用户名 + * @return 权限集合 + */ + @Override + public Set getUserPermissionsSet(String username) { + Set permissionSet = new HashSet<>(); + List permissionList = sysPermissionMapper.queryByUser(username); + for (SysPermission po : permissionList) { +// // TODO URL规则有问题? +// if (oConvertUtils.isNotEmpty(po.getUrl())) { +// permissionSet.add(po.getUrl()); +// } + if (oConvertUtils.isNotEmpty(po.getPerms())) { + permissionSet.add(po.getPerms()); + } + } + log.info("-------通过数据库读取用户拥有的权限Perms------username: " + username + ",Perms size: " + (permissionSet == null ? 0 : permissionSet.size())); + return permissionSet; + } + + /** + * 升级SpringBoot2.6.6,不允许循环依赖 + * + * @param username + * @return + * @author:qinfeng + * @update: 2022-04-07 + */ + @Override + @Cacheable(cacheNames = CacheConstant.SYS_USERS_CACHE, key = "#username") + public SysUserCacheInfo getCacheUser(String username) { + SysUserCacheInfo info = new SysUserCacheInfo(); + info.setOneDepart(true); + if (oConvertUtils.isEmpty(username)) { + return null; + } + + //查询用户信息 + SysUser sysUser = userMapper.getUserByName(username); + if (sysUser != null) { + info.setSysUserCode(sysUser.getUsername()); + info.setSysUserName(sysUser.getRealname()); +// info.setSysOrgCode(sysUser.getOrgCode()); + } + + //多部门支持in查询 +// List list = sysDepartMapper.queryUserDeparts(sysUser.getId()); +// List sysMultiOrgCode = new ArrayList(); +// if (list == null || list.size() == 0) { +// 当前用户无部门 +// sysMultiOrgCode.add("0"); +// } else if (list.size() == 1) { +// sysMultiOrgCode.add(list.get(0).getOrgCode()); +// } else { +// info.setOneDepart(false); +// for (SysDepart dpt : list) { +// sysMultiOrgCode.add(dpt.getOrgCode()); +// } +// } +// info.setSysMultiOrgCode(sysMultiOrgCode); + + return info; + } + + /** + * 根据部门Id查询 + * + * @param page + * @param departId 部门id + * @param username 用户账户名称 + * @return + */ + @Override + public IPage getUserByDepId(Page page, String departId, String username) { + return userMapper.getUserByDepId(page, departId, username); + } + + @Override + public IPage getUserByDepIds(Page page, List departIds, String username) { + return userMapper.getUserByDepIds(page, departIds, username); + } + + @Override + public Map getDepNamesByUserIds(List userIds) { + List list = this.baseMapper.getDepNamesByUserIds(userIds); + + Map res = new HashMap(5); + list.forEach(item -> { + if (res.get(item.getUserId()) == null) { + res.put(item.getUserId(), item.getDepartName()); + } else { + res.put(item.getUserId(), res.get(item.getUserId()) + "," + item.getDepartName()); + } + } + ); + return res; + } + + @Override + public IPage getUserByDepartIdAndQueryWrapper(Page page, String departId, QueryWrapper queryWrapper) { + LambdaQueryWrapper lambdaQueryWrapper = queryWrapper.lambda(); + + lambdaQueryWrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_0); + lambdaQueryWrapper.inSql(SysUser::getId, "SELECT user_id FROM sys_user_depart WHERE dep_id = '" + departId + "'"); + + return userMapper.selectPage(page, lambdaQueryWrapper); + } + + @Override + public IPage queryUserByOrgCode(String orgCode, SysUser userParams, IPage page) { + List list = baseMapper.getUserByOrgCode(page, orgCode, userParams); + Integer total = baseMapper.getUserByOrgCodeTotal(orgCode, userParams); + + IPage result = new Page<>(page.getCurrent(), page.getSize(), total); + result.setRecords(list); + + return result; + } + + /** + * 根据角色Id查询 + * + * @param page + * @param roleId 角色id + * @param username 用户账户名称 + * @return + */ + @Override + public IPage getUserByRoleId(Page page, String roleId, String username) { + return userMapper.getUserByRoleId(page, roleId, username); + } + + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, key = "#username") + public void updateUserDepart(String username, String orgCode) { + baseMapper.updateUserDepart(username, orgCode); + } + + + @Override + public SysUser getUserByPhone(String phone) { + return userMapper.getUserByPhone(phone); + } + + + @Override + public SysUser getUserByEmail(String email) { + return userMapper.getUserByEmail(email); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void addUserWithDepart(SysUser user, String selectedParts) { +// this.save(user); //保存角色的时候已经添加过一次了 + if (oConvertUtils.isNotEmpty(selectedParts)) { + String[] arr = selectedParts.split(","); + for (String deaprtId : arr) { +// SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId); +// sysUserDepartMapper.insert(userDeaprt); + } + } + } + + + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + public void editUserWithDepart(SysUser user, String departs) { + //更新角色的时候已经更新了一次了,可以再跟新一次 + this.updateById(user); + String[] arr = {}; + if (oConvertUtils.isNotEmpty(departs)) { + arr = departs.split(","); + } + //查询已关联部门 + List userDepartList = sysUserDepartMapper.selectList(new QueryWrapper().lambda().eq(SysUserDepart::getUserId, user.getId())); + if (userDepartList != null && userDepartList.size() > 0) { + for (SysUserDepart depart : userDepartList) { + //修改已关联部门删除部门用户角色关系 + if (!Arrays.asList(arr).contains(depart.getDepId())) { + List sysDepartRoleList = sysDepartRoleMapper.selectList( + new QueryWrapper().lambda().eq(SysDepartRole::getDepartId, depart.getDepId())); + List roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList()); + if (roleIds != null && roleIds.size() > 0) { + departRoleUserMapper.delete(new QueryWrapper().lambda().eq(SysDepartRoleUser::getUserId, user.getId()) + .in(SysDepartRoleUser::getDroleId, roleIds)); + } + } + } + } + //先删后加 + sysUserDepartMapper.delete(new QueryWrapper().lambda().eq(SysUserDepart::getUserId, user.getId())); + if (oConvertUtils.isNotEmpty(departs)) { + for (String departId : arr) { +// SysUserDepart userDepart = new SysUserDepart(user.getId(), departId); +// sysUserDepartMapper.insert(userDepart); + } + } + } + + + /** + * 校验用户是否有效 + * + * @param sysUser + * @return + */ + @Override + public Result checkUserIsEffective(SysUser sysUser) { + Result result = new Result(); + //情况1:根据用户信息查询,该用户不存在 + if (sysUser == null) { + result.error500("该用户不存在,请注册"); + baseCommonService.addLog("用户登录失败,用户不存在!", CommonConstant.LOG_TYPE_1, null); + return result; + } + //情况2:根据用户信息查询,该用户已注销 + //update-begin---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + if (CommonConstant.DEL_FLAG_1.equals(sysUser.getDelFlag())) { + //update-end---author:王帅 Date:20200601 for:if条件永远为falsebug------------ + baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已注销!", CommonConstant.LOG_TYPE_1, null); + result.error500("该用户已注销"); + return result; + } + //情况3:根据用户信息查询,该用户已冻结 + if (CommonConstant.USER_FREEZE.equals(sysUser.getStatus())) { + baseCommonService.addLog("用户登录失败,用户名:" + sysUser.getUsername() + "已冻结!", CommonConstant.LOG_TYPE_1, null); + result.error500("该用户已冻结"); + return result; + } + return result; + } + + @Override + public List queryLogicDeleted() { + return this.queryLogicDeleted(null); + } + + @Override + public List queryLogicDeleted(LambdaQueryWrapper wrapper) { + if (wrapper == null) { + wrapper = new LambdaQueryWrapper<>(); + } + wrapper.eq(SysUser::getDelFlag, CommonConstant.DEL_FLAG_1); + return userMapper.selectLogicDeleted(wrapper); + } + + @Override + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + public boolean revertLogicDeleted(List userIds, SysUser updateEntity) { + String ids = String.format("'%s'", String.join("','", userIds)); + return userMapper.revertLogicDeleted(ids, updateEntity) > 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean removeLogicDeleted(List userIds) { + String ids = String.format("'%s'", String.join("','", userIds)); + // 1. 删除用户 + int line = userMapper.deleteLogicDeleted(ids); + // 2. 删除用户部门关系 + line += sysUserDepartMapper.delete(new LambdaQueryWrapper().in(SysUserDepart::getUserId, userIds)); + //3. 删除用户角色关系 + line += sysUserRoleMapper.delete(new LambdaQueryWrapper().in(SysUserRole::getUserId, userIds)); + //4.同步删除第三方App的用户 + try { +// dingtalkService.removeThirdAppUser(userIds); +// wechatEnterpriseService.removeThirdAppUser(userIds); + } catch (Exception e) { + log.error("同步删除第三方App的用户失败:", e); + } + //5. 删除第三方用户表(因为第4步需要用到第三方用户表,所以在他之后删) + line += sysThirdAccountMapper.delete(new LambdaQueryWrapper().in(SysThirdAccount::getSysUserId, userIds)); + + return line != 0; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public boolean updateNullPhoneEmail() { + userMapper.updateNullByEmptyString("email"); + userMapper.updateNullByEmptyString("phone"); + return true; + } + + @Override + public void saveThirdUser(SysUser sysUser) { + //保存用户 + String userid = UUIDGenerator.generate(); +// sysUser.setId(userid); +// baseMapper.insert(sysUser); + //获取第三方角色 + SysRole sysRole = sysRoleMapper.selectOne(new LambdaQueryWrapper().eq(SysRole::getRoleCode, "third_role")); + //保存用户角色 + SysUserRole userRole = new SysUserRole(); + userRole.setRoleId(sysRole.getId()); + userRole.setUserId(userid); + sysUserRoleMapper.insert(userRole); + } + + @Override + public List queryByDepIds(List departIds, String username) { + return userMapper.queryByDepIds(departIds, username); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public void saveUser(SysUser user, String selectedRoles, String selectedDeparts) { + //step.1 保存用户 + user.setRealname(user.getUsername()); + this.save(user); + //step.2 保存角色 + if (oConvertUtils.isNotEmpty(selectedRoles)) { + String[] arr = selectedRoles.split(","); + for (String roleId : arr) { +// SysUserRole userRole = new SysUserRole(user.getId(), roleId); +// sysUserRoleMapper.insert(userRole); + } + } + //step.3 保存所属部门 + if (oConvertUtils.isNotEmpty(selectedDeparts)) { + String[] arr = selectedDeparts.split(","); + for (String deaprtId : arr) { +// SysUserDepart userDeaprt = new SysUserDepart(user.getId(), deaprtId); +// sysUserDepartMapper.insert(userDeaprt); + } + } + } + + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = {CacheConstant.SYS_USERS_CACHE}, allEntries = true) + public void editUser(SysUser user, String roles, String departs) { + //step.1 修改用户基础信息 + this.updateById(user); + //step.2 修改角色 + //处理用户角色 先删后加 + sysUserRoleMapper.delete(new QueryWrapper().lambda().eq(SysUserRole::getUserId, user.getId())); + if (oConvertUtils.isNotEmpty(roles)) { + String[] arr = roles.split(","); + for (String roleId : arr) { +// SysUserRole userRole = new SysUserRole(user.getId(), roleId); +// sysUserRoleMapper.insert(userRole); + } + } + + //step.3 修改部门 + String[] arr = {}; + if (oConvertUtils.isNotEmpty(departs)) { + arr = departs.split(","); + } + //查询已关联部门 + List userDepartList = sysUserDepartMapper.selectList(new QueryWrapper().lambda().eq(SysUserDepart::getUserId, user.getId())); + if (userDepartList != null && userDepartList.size() > 0) { + for (SysUserDepart depart : userDepartList) { + //修改已关联部门删除部门用户角色关系 + if (!Arrays.asList(arr).contains(depart.getDepId())) { + List sysDepartRoleList = sysDepartRoleMapper.selectList( + new QueryWrapper().lambda().eq(SysDepartRole::getDepartId, depart.getDepId())); + List roleIds = sysDepartRoleList.stream().map(SysDepartRole::getId).collect(Collectors.toList()); + if (roleIds != null && roleIds.size() > 0) { + departRoleUserMapper.delete(new QueryWrapper().lambda().eq(SysDepartRoleUser::getUserId, user.getId()) + .in(SysDepartRoleUser::getDroleId, roleIds)); + } + } + } + } + //先删后加 + sysUserDepartMapper.delete(new QueryWrapper().lambda().eq(SysUserDepart::getUserId, user.getId())); + if (oConvertUtils.isNotEmpty(departs)) { + for (String departId : arr) { +// SysUserDepart userDepart = new SysUserDepart(user.getId(), departId); +// sysUserDepartMapper.insert(userDepart); + } + } + //step.4 修改手机号和邮箱 + // 更新手机号、邮箱空字符串为 null + userMapper.updateNullByEmptyString("email"); + userMapper.updateNullByEmptyString("phone"); + + } + + @Override + public List userIdToUsername(Collection userIdList) { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.in(SysUser::getId, userIdList); + List userList = super.list(queryWrapper); + return userList.stream().map(SysUser::getUsername).collect(Collectors.toList()); + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysVersionServiceImpl.java b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysVersionServiceImpl.java new file mode 100644 index 0000000..437c93c --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/service/impl/SysVersionServiceImpl.java @@ -0,0 +1,33 @@ +package digital.system.jeecg.system.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import digital.system.jeecg.system.entity.SysVersion; +import digital.system.jeecg.system.mapper.SysVersionMapper; +import digital.system.jeecg.system.service.ISysVersionService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import java.util.List; + +@Service +public class SysVersionServiceImpl extends ServiceImpl implements ISysVersionService { + + @Autowired + private SysVersionMapper sysVersionMapper; + + @Override + public String queryVersion() { + List sysVersions = sysVersionMapper.selectList(new QueryWrapper<>()); + SysVersion sysVersion = sysVersions.get(0); + return sysVersion.getReleaseVersion(); + } + + @Override + public SysVersion queryVersionInfo() { + List sysVersions = sysVersionMapper.selectList(new QueryWrapper<>()); + SysVersion sysVersion = sysVersions.get(0); + return sysVersion; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/util/FindsDepartsChildrenUtil.java b/digital-system/src/main/java/digital/system/jeecg/system/util/FindsDepartsChildrenUtil.java new file mode 100644 index 0000000..5478431 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/util/FindsDepartsChildrenUtil.java @@ -0,0 +1,129 @@ +package digital.system.jeecg.system.util; + + +import digital.system.jeecg.system.model.DepartIdModel; +import digital.system.jeecg.system.model.SysDepartTreeModel; +import digital.system.jeecg.system.entity.SysDepart; +import digital.util.util.oConvertUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + *

+ * 对应部门的表,处理并查找树级数据 + *

+ * + * @Author: Steve + * @Date: 2019-01-22 + */ +public class FindsDepartsChildrenUtil { + + //部门树信息-树结构 + //private static List sysDepartTreeList = new ArrayList(); + + //部门树id-树结构 + //private static List idList = new ArrayList<>(); + + + /** + * queryTreeList的子方法 ====1===== + * 该方法是s将SysDepart类型的list集合转换成SysDepartTreeModel类型的集合 + */ + public static List wrapTreeDataToTreeList(List recordList) { + // 在该方法每请求一次,都要对全局list集合进行一次清理 + //idList.clear(); + List idList = new ArrayList(); + List records = new ArrayList<>(); + for (int i = 0; i < recordList.size(); i++) { + SysDepart depart = recordList.get(i); + records.add(new SysDepartTreeModel(depart)); + } + List tree = findChildren(records, idList); + setEmptyChildrenAsNull(tree); + return tree; + } + + /** + * 获取 DepartIdModel + * + * @param recordList + * @return + */ + public static List wrapTreeDataToDepartIdTreeList(List recordList) { + // 在该方法每请求一次,都要对全局list集合进行一次清理 + //idList.clear(); + List idList = new ArrayList(); + List records = new ArrayList<>(); + for (int i = 0; i < recordList.size(); i++) { + SysDepart depart = recordList.get(i); + records.add(new SysDepartTreeModel(depart)); + } + findChildren(records, idList); + return idList; + } + + /** + * queryTreeList的子方法 ====2===== + * 该方法是找到并封装顶级父类的节点到TreeList集合 + */ + private static List findChildren(List recordList, + List departIdList) { + + List treeList = new ArrayList<>(); + for (int i = 0; i < recordList.size(); i++) { + SysDepartTreeModel branch = recordList.get(i); + if (oConvertUtils.isEmpty(branch.getParentId())) { + treeList.add(branch); + DepartIdModel departIdModel = new DepartIdModel().convert(branch); + departIdList.add(departIdModel); + } + } + getGrandChildren(treeList, recordList, departIdList); + + //idList = departIdList; + return treeList; + } + + /** + * queryTreeList的子方法====3==== + * 该方法是找到顶级父类下的所有子节点集合并封装到TreeList集合 + */ + private static void getGrandChildren(List treeList, List recordList, List idList) { + + for (int i = 0; i < treeList.size(); i++) { + SysDepartTreeModel model = treeList.get(i); + DepartIdModel idModel = idList.get(i); + for (int i1 = 0; i1 < recordList.size(); i1++) { + SysDepartTreeModel m = recordList.get(i1); + if (m.getParentId() != null && m.getParentId().equals(model.getId())) { + model.getChildren().add(m); + DepartIdModel dim = new DepartIdModel().convert(m); + idModel.getChildren().add(dim); + } + } + getGrandChildren(treeList.get(i).getChildren(), recordList, idList.get(i).getChildren()); + } + + } + + + /** + * queryTreeList的子方法 ====4==== + * 该方法是将子节点为空的List集合设置为Null值 + */ + private static void setEmptyChildrenAsNull(List treeList) { + + for (int i = 0; i < treeList.size(); i++) { + SysDepartTreeModel model = treeList.get(i); + if (model.getChildren().size() == 0) { + model.setChildren(null); + model.setIsLeaf(true); + } else { + setEmptyChildrenAsNull(model.getChildren()); + model.setIsLeaf(false); + } + } + // sysDepartTreeList = treeList; + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/util/PermissionDataUtil.java b/digital-system/src/main/java/digital/system/jeecg/system/util/PermissionDataUtil.java new file mode 100644 index 0000000..71df2b7 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/util/PermissionDataUtil.java @@ -0,0 +1,97 @@ +package digital.system.jeecg.system.util; + +import digital.system.jeecg.system.entity.SysPermission; +import digital.util.util.oConvertUtils; + +import java.util.List; + +/** + * @Author: scott + * @Date: 2019-04-03 + */ +public class PermissionDataUtil { + + /** + * 智能处理错误数据,简化用户失误操作 + * + * @param permission + */ + public static SysPermission intelligentProcessData(SysPermission permission) { + if (permission == null) { + return null; + } + + // 组件 + if (oConvertUtils.isNotEmpty(permission.getComponent())) { + String component = permission.getComponent(); + if (component.startsWith("/")) { + component = component.substring(1); + } + if (component.startsWith("views/")) { + component = component.replaceFirst("views/", ""); + } + if (component.startsWith("src/views/")) { + component = component.replaceFirst("src/views/", ""); + } + if (component.endsWith(".vue")) { + component = component.replace(".vue", ""); + } + permission.setComponent(component); + } + + // 请求URL + if (oConvertUtils.isNotEmpty(permission.getUrl())) { + String url = permission.getUrl(); + if (url.endsWith(".vue")) { + url = url.replace(".vue", ""); + } + if (!url.startsWith("http") && !url.startsWith("/") && !url.trim().startsWith("{{")) { + url = "/" + url; + } + permission.setUrl(url); + } + + // 一级菜单默认组件 + if (0 == permission.getMenuType() && oConvertUtils.isEmpty(permission.getComponent())) { + // 一级菜单默认组件 + permission.setComponent("layouts/RouteView"); + } + return permission; + } + + /** + * 如果没有index页面 需要new 一个放到list中 + * + * @param metaList + */ + public static void addIndexPage(List metaList) { + boolean hasIndexMenu = false; + for (SysPermission sysPermission : metaList) { + if ("首页".equals(sysPermission.getName())) { + hasIndexMenu = true; + break; + } + } + if (!hasIndexMenu) { + metaList.add(0, new SysPermission(true)); + } + } + + /** + * 判断是否授权首页 + * + * @param metaList + * @return + */ + public static boolean hasIndexPage(List metaList) { + boolean hasIndexMenu = false; + for (SysPermission sysPermission : metaList) { + if ("首页".equals(sysPermission.getName())) { + hasIndexMenu = true; + break; + } + } + return hasIndexMenu; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/util/RandImageUtil.java b/digital-system/src/main/java/digital/system/jeecg/system/util/RandImageUtil.java new file mode 100644 index 0000000..69b4df0 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/util/RandImageUtil.java @@ -0,0 +1,148 @@ +package digital.system.jeecg.system.util; + +import javax.imageio.ImageIO; +import javax.servlet.http.HttpServletResponse; +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Base64; +import java.util.Random; + +/** + * 登录验证码工具类 + * + * @author: smcp + */ +public class RandImageUtil { + + public static final String key = "JEECG_LOGIN_KEY"; + + /** + * 定义图形大小 + */ + private static final int width = 105; + /** + * 定义图形大小 + */ + private static final int height = 35; + + /** + * 定义干扰线数量 + */ + private static final int count = 200; + + /** + * 干扰线的长度=1.414*lineWidth + */ + private static final int lineWidth = 2; + + /** + * 图片格式 + */ + private static final String IMG_FORMAT = "JPEG"; + + /** + * base64 图片前缀 + */ + private static final String BASE64_PRE = "data:image/jpg;base64,"; + + /** + * 直接通过response 返回图片 + * + * @param response + * @param resultCode + * @throws IOException + */ + public static void generate(HttpServletResponse response, String resultCode) throws IOException { + BufferedImage image = getImageBuffer(resultCode); + // 输出图象到页面 + ImageIO.write(image, IMG_FORMAT, response.getOutputStream()); + } + + /** + * 生成base64字符串 + * + * @param resultCode + * @return + * @throws IOException + */ + public static String generate(String resultCode) throws IOException { + BufferedImage image = getImageBuffer(resultCode); + + ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); + //写入流中 + ImageIO.write(image, IMG_FORMAT, byteStream); + //转换成字节 + byte[] bytes = byteStream.toByteArray(); + //转换成base64串 + String base64 = Base64.getEncoder().encodeToString(bytes).trim(); + //删除 \r\n + base64 = base64.replaceAll("\n", "").replaceAll("\r", ""); + + //写到指定位置 + //ImageIO.write(bufferedImage, "png", new File("")); + + return BASE64_PRE + base64; + } + + private static BufferedImage getImageBuffer(String resultCode) { + // 在内存中创建图象 + final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + // 获取图形上下文 + final Graphics2D graphics = (Graphics2D) image.getGraphics(); + // 设定背景颜色 + // ---1 + graphics.setColor(Color.WHITE); + graphics.fillRect(0, 0, width, height); + // 设定边框颜色 +// graphics.setColor(getRandColor(100, 200)); // ---2 + graphics.drawRect(0, 0, width - 1, height - 1); + + final Random random = new Random(); + // 随机产生干扰线,使图象中的认证码不易被其它程序探测到 + for (int i = 0; i < count; i++) { + // ---3 + graphics.setColor(getRandColor(150, 200)); + + // 保证画在边框之内 + final int x = random.nextInt(width - lineWidth - 1) + 1; + final int y = random.nextInt(height - lineWidth - 1) + 1; + final int xl = random.nextInt(lineWidth); + final int yl = random.nextInt(lineWidth); + graphics.drawLine(x, y, x + xl, y + yl); + } + // 取随机产生的认证码 + for (int i = 0; i < resultCode.length(); i++) { + // 将认证码显示到图象中,调用函数出来的颜色相同,可能是因为种子太接近,所以只能直接生成 + // graphics.setColor(new Color(20 + random.nextInt(130), 20 + random + // .nextInt(130), 20 + random.nextInt(130))); + // 设置字体颜色 + graphics.setColor(Color.BLACK); + // 设置字体样式 +// graphics.setFont(new Font("Arial Black", Font.ITALIC, 18)); + graphics.setFont(new Font("Times New Roman", Font.BOLD, 24)); + // 设置字符,字符间距,上边距 + graphics.drawString(String.valueOf(resultCode.charAt(i)), (23 * i) + 8, 26); + } + // 图象生效 + graphics.dispose(); + return image; + } + + private static Color getRandColor(int fc, int bc) { // 取得给定范围随机颜色 + final Random random = new Random(); + if (fc > 255) { + fc = 255; + } + if (bc > 255) { + bc = 255; + } + + final int r = fc + random.nextInt(bc - fc); + final int g = fc + random.nextInt(bc - fc); + final int b = fc + random.nextInt(bc - fc); + + return new Color(r, g, b); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/util/SecurityUtil.java b/digital-system/src/main/java/digital/system/jeecg/system/util/SecurityUtil.java new file mode 100644 index 0000000..b390e26 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/util/SecurityUtil.java @@ -0,0 +1,59 @@ +package digital.system.jeecg.system.util; + + +import cn.hutool.core.util.CharsetUtil; +import cn.hutool.crypto.symmetric.SymmetricAlgorithm; +import cn.hutool.crypto.symmetric.SymmetricCrypto; + +/** + * @Description: 密码加密解密 + * @author: lsq + * @date: 2020年09月07日 14:26 + */ +public class SecurityUtil { + /** + * 加密key + */ + private static String key = "JEECGBOOT1423670"; + + //---AES加密---------begin--------- + + /** + * 加密 + * + * @param content + * @return + */ + public static String jiami(String content) { + SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes()); + String encryptResultStr = aes.encryptHex(content); + return encryptResultStr; + } + + /** + * 解密 + * + * @param encryptResultStr + * @return + */ + public static String jiemi(String encryptResultStr) { + SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, key.getBytes()); + //解密为字符串 + String decryptResult = aes.decryptStr(encryptResultStr, CharsetUtil.CHARSET_UTF_8); + return decryptResult; + } + //---AES加密---------end--------- + + /** + * 主函数 + */ + public static void main(String[] args) { + String content = "test1111"; + String encrypt = jiami(content); + System.out.println(encrypt); + //构建 + String decrypt = jiemi(encrypt); + //解密为字符串 + System.out.println(decrypt); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/util/XSSUtils.java b/digital-system/src/main/java/digital/system/jeecg/system/util/XSSUtils.java new file mode 100644 index 0000000..67e0a47 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/util/XSSUtils.java @@ -0,0 +1,44 @@ +package digital.system.jeecg.system.util; + +import org.springframework.web.util.HtmlUtils; + +import java.util.regex.Pattern; + +/** + * @Description: 工具类XSSUtils,现在的做法是替换成空字符,CSDN的是进行转义,比如文字开头的"<"转成< + * @author: lsq + * @date: 2021年07月26日 19:13 + */ +public class XSSUtils { + public static String striptXSS(String value) { + if (value != null) { + value = value.replaceAll(" ", ""); + Pattern scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\'(.*?)\\\'", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("src[\r\n]*=[\r\n]*\\\"(.*?)\\\"", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("eval\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("e­xpression\\((.*?)\\)", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("javascript:", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("vbscript:", Pattern.CASE_INSENSITIVE); + value = scriptPattern.matcher(value).replaceAll(""); + scriptPattern = Pattern.compile("onload(.*?)=", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); + value = scriptPattern.matcher(value).replaceAll(""); + } + return HtmlUtils.htmlEscape(value); + } + + public static void main(String[] args) { + String s = striptXSS("javascript:eval()\\\\."); + System.err.println("s======>" + s); + } +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDepartUsersVO.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDepartUsersVO.java new file mode 100644 index 0000000..f778c38 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDepartUsersVO.java @@ -0,0 +1,37 @@ +package digital.system.jeecg.system.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description: 系统部门VO + * @author: smcp + */ +@Data +public class SysDepartUsersVO implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 部门id + */ + private String depId; + /** + * 对应的用户id集合 + */ + private List userIdList; + + public SysDepartUsersVO(String depId, List userIdList) { + super(); + this.depId = depId; + this.userIdList = userIdList; + } + //update-begin--Author:kangxiaolin Date:20190908 for:[512][部门管理]点击添加已有用户失败修复-------------------- + + public SysDepartUsersVO() { + + } + //update-begin--Author:kangxiaolin Date:20190908 for:[512][部门管理]点击添加已有用户失败修复-------------------- + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDictPage.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDictPage.java new file mode 100644 index 0000000..ebe9c7e --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysDictPage.java @@ -0,0 +1,47 @@ +package digital.system.jeecg.system.vo; + +import com.baomidou.mybatisplus.annotation.TableLogic; +import lombok.Data; +import org.jeecgframework.poi.excel.annotation.Excel; +import org.jeecgframework.poi.excel.annotation.ExcelCollection; +import digital.system.jeecg.system.entity.SysDictItem; + +import java.util.List; + +/** + * @Description: 系统字典分页 + * @author: smcp + */ +@Data +public class SysDictPage { + + /** + * 主键 + */ + private String id; + /** + * 字典名称 + */ + @Excel(name = "字典名称", width = 20) + private String dictName; + + /** + * 字典编码 + */ + @Excel(name = "字典编码", width = 30) + private String dictCode; + /** + * 删除状态 + */ + @TableLogic + private Integer delFlag; + /** + * 描述 + */ + @Excel(name = "描述", width = 30) + private String description; + + @ExcelCollection(name = "字典列表") + private List sysDictItemList; + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserDepVo.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserDepVo.java new file mode 100644 index 0000000..4313ec3 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserDepVo.java @@ -0,0 +1,15 @@ +package digital.system.jeecg.system.vo; + +import lombok.Data; + +/** + * @Author qinfeng + * @Date 2020/1/2 21:58 + * @Description: + * @Version 1.0 + */ +@Data +public class SysUserDepVo { + private String userId; + private String departName; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserOnlineVO.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserOnlineVO.java new file mode 100644 index 0000000..2266cdc --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserOnlineVO.java @@ -0,0 +1,59 @@ +package digital.system.jeecg.system.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import org.springframework.format.annotation.DateTimeFormat; +import digital.base.annotation.Dict; + +import java.util.Date; + +/** + * @Author: chenli + * @Date: 2020-06-07 + * @Version: V1.0 + */ +@Data +public class SysUserOnlineVO { + /** + * 会话id + */ + private String id; + + /** + * 会话编号 + */ + private String token; + + /** + * 用户名 + */ + private String username; + + /** + * 用户名 + */ + private String realname; + + /** + * 头像 + */ + private String avatar; + + /** + * 生日 + */ + @JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd") + @DateTimeFormat(pattern = "yyyy-MM-dd") + private Date birthday; + + /** + * 性别(1:男 2:女) + */ + @Dict(dicCode = "sex") + private Integer sex; + + /** + * 手机号 + */ + private String phone; +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserRoleVO.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserRoleVO.java new file mode 100644 index 0000000..f182547 --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserRoleVO.java @@ -0,0 +1,35 @@ +package digital.system.jeecg.system.vo; + +import lombok.Data; + +import java.io.Serializable; +import java.util.List; + +/** + * @Description: 用户角色vo + * @author: smcp + */ +@Data +public class SysUserRoleVO implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * 部门id + */ + private String roleId; + /** + * 对应的用户id集合 + */ + private List userIdList; + + public SysUserRoleVO() { + super(); + } + + public SysUserRoleVO(String roleId, List userIdList) { + super(); + this.roleId = roleId; + this.userIdList = userIdList; + } + +} diff --git a/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserVO.java b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserVO.java new file mode 100644 index 0000000..608bdbf --- /dev/null +++ b/digital-system/src/main/java/digital/system/jeecg/system/vo/SysUserVO.java @@ -0,0 +1,13 @@ +package digital.system.jeecg.system.vo; + +import lombok.Data; +import digital.system.jeecg.system.entity.SysUser; + +@Data +public class SysUserVO { + + private String token; + + private SysUser sysUser; + +} diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1f83057 --- /dev/null +++ b/pom.xml @@ -0,0 +1,427 @@ + + 4.0.0 + org.jeecgframework.boot + jeecg-boot-parent + 3.2.0 + pom + JEECG BOOT ${project.version} + + + org.springframework.boot + spring-boot-starter-parent + 2.6.6 + + + + + 3.2.0 + 1.8 + UTF-8 + + + false + 2021.0.3 + 2021.1 + 2.0.4 + + 2.2.0 + 1.2.83 + 3.0.3 + 2.0.9 + + 42.2.6 + 11.2.0.3 + 4.0 + 8.0.27 + 5.8.26 + + 1.9.4 + 29.0-jre + + + 3.5.1 + 3.2.0 + 1.9.0 + 1.1.22 + 2.6 + 2.1.0 + 3.11.2 + + 1.9.1 + 3.11.0 + 3.1.0 + 1.3.9 + 1.4.0 + 8.0.3 + 1.3.4 + 1.6.1 + 7.4.0 + + 2.17.0 + 1.2.9 + + + + digital-common + digital-application + digital-system + + + + + jeecg + jeecg Repository + http://maven.jeecg.com:8090/nexus/content/repositories/jeecg + + + jeecg-snapshots + jeecg Snapshot Repository + http://maven.jeecg.com:8090/nexus/content/repositories/snapshots/ + + + + + aliyun + aliyun Repository + https://maven.aliyun.com/repository/public + + false + + + + jeecg + jeecg Repository + https://maven.jeecg.org/nexus/content/repositories/jeecg + + false + + + + + + + org.projectlombok + lombok + 1.18.20 + provided + + + + org.springframework.boot + spring-boot-starter-test + test + + + junit + junit + test + + + + org.projectlombok + lombok + + + + com.alibaba + fastjson + ${fastjson.version} + + + + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + com.alibaba.cloud + spring-cloud-alibaba-dependencies + ${spring-cloud-alibaba.version} + pom + import + + + + + org.jeecgframework.boot + jeecg-boot-base-tools + ${jeecgboot.version} + + + + + + + + + + + + + + + org.hibernate + hibernate-core + 5.6.7.Final + + + commons-collections + commons-collections + + + + + org.jeecgframework.boot + hibernate-re + 3.2.1-beta + + + + + dom4j + dom4j + ${dom4j.version} + + + + + + + + + + + com.google.guava + guava + ${guava.version} + + + + + cn.hutool + hutool-core + ${hutool.version} + + + cn.hutool + hutool-crypto + ${hutool.version} + + + + commons-beanutils + commons-beanutils + ${commons-beanutils.version} + + + + commons-fileupload + commons-fileupload + 1.4 + + + commons-io + commons-io + + + + + + + com.xkcoding.justauth + justauth-spring-boot-starter + ${justauth-spring-boot-starter.version} + + + hutool-core + cn.hutool + + + fastjson + com.alibaba + + + + + com.squareup.okhttp3 + okhttp + 4.4.1 + + + + io.minio + minio + ${minio.version} + + + okio + com.squareup.okio + + + okhttp + com.squareup.okhttp3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.8 + 1.8 + UTF-8 + + + + + org.apache.maven.plugins + maven-surefire-plugin + + true + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.1.0 + + + woff + woff2 + eot + ttf + svg + + + + + + + src/main/resources + true + + + src/main/java + + **/*.xml + **/*.json + **/*.ftl + + + + + + + + + dev + + + true + + + + dev + + jeecg + + jeecg-boot-nacos:8848 + + + + nacos + + nacos + + DEFAULT_GROUP + + jeecg-boot-nacos:8848 + + + + + test + + + test + + jeecg + + jeecg-boot-nacos:8848 + + + + nacos + + nacos + + DEFAULT_GROUP + + jeecg-boot-nacos:8848 + + + + + prod + + + prod + + jeecg + + jeecg-boot-nacos:8848 + + + + nacos + + nacos + + DEFAULT_GROUP + + jeecg-boot-nacos:8848 + + + + + SpringCloud + + + false + + + + \ No newline at end of file